Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

inotify: Avoid reporting event with invalid wd

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: 7e790dd5fc93 ("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 <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>

Jan Kara c915d8f5 173ea743

+9 -2
+9 -2
fs/notify/inotify/inotify_fsnotify.c
··· 65 65 struct fsnotify_event *fsn_event; 66 66 struct fsnotify_group *group = inode_mark->group; 67 67 int ret; 68 - int len = 0; 68 + int len = 0, wd; 69 69 int alloc_len = sizeof(struct inotify_event_info); 70 70 struct mem_cgroup *old_memcg; 71 71 ··· 80 80 i_mark = container_of(inode_mark, struct inotify_inode_mark, 81 81 fsn_mark); 82 82 83 + /* 84 + * We can be racing with mark being detached. Don't report event with 85 + * invalid wd. 86 + */ 87 + wd = READ_ONCE(i_mark->wd); 88 + if (wd == -1) 89 + return 0; 83 90 /* 84 91 * Whoever is interested in the event, pays for the allocation. Do not 85 92 * trigger OOM killer in the target monitoring memcg as it may have ··· 117 110 fsn_event = &event->fse; 118 111 fsnotify_init_event(fsn_event); 119 112 event->mask = mask; 120 - event->wd = i_mark->wd; 113 + event->wd = wd; 121 114 event->sync_cookie = cookie; 122 115 event->name_len = len; 123 116 if (len)