| From c915d8f5918bea7c3962b09b8884ca128bfd9b0c Mon Sep 17 00:00:00 2001 |
| From: Jan Kara <jack@suse.cz> |
| Date: Mon, 24 Apr 2023 18:32:19 +0200 |
| Subject: inotify: Avoid reporting event with invalid wd |
| |
| From: Jan Kara <jack@suse.cz> |
| |
| 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: 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/notify/inotify/inotify_fsnotify.c | 11 +++++++++-- |
| 1 file changed, 9 insertions(+), 2 deletions(-) |
| |
| --- a/fs/notify/inotify/inotify_fsnotify.c |
| +++ b/fs/notify/inotify/inotify_fsnotify.c |
| @@ -65,7 +65,7 @@ int inotify_handle_inode_event(struct fs |
| struct fsnotify_event *fsn_event; |
| struct fsnotify_group *group = inode_mark->group; |
| int ret; |
| - int len = 0; |
| + int len = 0, wd; |
| int alloc_len = sizeof(struct inotify_event_info); |
| struct mem_cgroup *old_memcg; |
| |
| @@ -81,6 +81,13 @@ int inotify_handle_inode_event(struct fs |
| 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 |
| * security repercussion. |
| @@ -110,7 +117,7 @@ int inotify_handle_inode_event(struct fs |
| fsn_event = &event->fse; |
| fsnotify_init_event(fsn_event); |
| event->mask = mask; |
| - event->wd = i_mark->wd; |
| + event->wd = wd; |
| event->sync_cookie = cookie; |
| event->name_len = len; |
| if (len) |