In the use case of buffered write whose input buffer is mmapped file on a filesystem with a pre-content mark, the prefaulting of the buffer can happen under the filesystem freeze protection (obtained in vfs_write()) which breaks assumptions of pre-content hook and introduces potential deadlock of HSM handler in userspace with filesystem freezing. Now that we have pre-content hooks at file mmap() time, disable the pre-content event hooks on page fault to avoid the potential deadlock. Leave the code of pre-content hooks in page fault because we may want to re-enable them on executables or user mapped files under certain conditions after resolving the potential deadlocks. Reported-by: syzbot+7229071b47908b19d5b7@xxxxxxxxxxxxxxxxxxxxxxxxx Closes: https://lore.kernel.org/linux-fsdevel/7ehxrhbvehlrjwvrduoxsao5k3x4aw275patsb3krkwuq573yv@o2hskrfawbnc/ Fixes: 8392bc2ff8c8b ("fsnotify: generate pre-content permission event on page fault") Suggested-by: Josef Bacik <josef@xxxxxxxxxxxxxx> Tested-by: syzbot+7229071b47908b19d5b7@xxxxxxxxxxxxxxxxxxxxxxxxx Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> --- include/linux/fsnotify.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 6a33288bd6a1f..796dacceec488 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -137,6 +137,14 @@ void file_set_fsnotify_mode_from_watchers(struct file *file); static inline int fsnotify_file_area_perm(struct file *file, int perm_mask, const loff_t *ppos, size_t count) { + /* + * Temporarily disable pre-content hooks from page faults (MAY_ACCESS). + * We may bring them back later either only to executables or to user + * mapped files under some conditions. + */ + if (!(perm_mask & (MAY_READ | MAY_WRITE))) + return 0; + /* * filesystem may be modified in the context of permission events * (e.g. by HSM filling a file on access), so sb freeze protection @@ -144,9 +152,6 @@ static inline int fsnotify_file_area_perm(struct file *file, int perm_mask, */ lockdep_assert_once(file_write_not_started(file)); - if (!(perm_mask & (MAY_READ | MAY_WRITE | MAY_ACCESS))) - return 0; - if (likely(!FMODE_FSNOTIFY_PERM(file->f_mode))) return 0; -- 2.34.1