From 27a22f0fbd8d1c00384295cabaf743526b4197f7 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 24 Apr 2023 18:32:19 +0200 Subject: [PATCH] inotify: Avoid reporting event with invalid wd commit c915d8f5918bea7c3962b09b8884ca128bfd9b0c upstream. When inotify_freeing_mark() races with inotify_handle_inode_event() it can happen that inotify_handle_inode_event() sees that i_mark->wd got already reset to -1 and reports this value to userspace which can confuse the inotify listener. Avoid the problem by validating that wd is sensible (and pretend the mark got removed before the event got generated otherwise). CC: stable@vger.kernel.org Fixes: cbb36f453190 ("inotify: fix error paths in inotify_update_watch") Message-Id: <20230424163219.9250-1-jack@suse.cz> Reported-by: syzbot+4a06d4373fd52f0b2f9c@syzkaller.appspotmail.com Reviewed-by: Amir Goldstein Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/notify/inotify/inotify_fsnotify.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 589dee9629938..a3cbfd38f1f63 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -66,7 +66,7 @@ int inotify_handle_event(struct fsnotify_group *group, struct inotify_event_info *event; struct fsnotify_event *fsn_event; int ret; - int len = 0; + int len = 0, wd; int alloc_len = sizeof(struct inotify_event_info); if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info))) @@ -90,6 +90,13 @@ int inotify_handle_event(struct fsnotify_group *group, i_mark = container_of(inode_mark, struct inotify_inode_mark, fsn_mark); + /* + * We can be racing with mark being detached. Don't report event with + * invalid wd. + */ + wd = READ_ONCE(i_mark->wd); + if (wd == -1) + return 0; /* * Whoever is interested in the event, pays for the allocation. Do not * trigger OOM killer in the target monitoring memcg as it may have @@ -120,7 +127,7 @@ int inotify_handle_event(struct fsnotify_group *group, fsn_event = &event->fse; fsnotify_init_event(fsn_event, (unsigned long)inode); event->mask = mask; - event->wd = i_mark->wd; + event->wd = wd; event->sync_cookie = cookie; event->name_len = len; if (len) -- 2.39.5