Skip to content

fanotify: Fix stale file descriptor in copy_event_to_user()

fanotify: Fix stale file descriptor in copy_event_to_user()

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2054337 CVE: CVE-2022-1998 Tested: xfstests -g auto Conflicts: The section with copy_info_to_user() calls is wrapped in the function upstream

commit ee12595147ac1fbfb5bcb23837e26dd58d94b15d Author: Dan Carpenter dan.carpenter@oracle.com Date: Fri Jan 28 22:57:01 2022 +0300 fanotify: Fix stale file descriptor in copy_event_to_user()

This code calls fd_install() which gives the userspace access to the fd. Then if copy_info_records_to_user() fails it calls put_unused_fd(fd) but that will not release it and leads to a stale entry in the file descriptor table.

Generally you can't trust the fd after a call to fd_install(). The fix is to delay the fd_install() until everything else has succeeded.

Fortunately it requires CAP_SYS_ADMIN to reach this code so the security impact is less.

Fixes: f644bc44 ("fanotify: fix copy_event_to_user() fid error clean up") Link: https://lore.kernel.org/r/20220128195656.GA26981@kili Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Mathias Krause minipli@grsecurity.net Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Andrey Albershteyn aalbersh@redhat.com

No reproducer was found. It seems to be a bug without a code path. The fd_install() (together with create_fd()/put_unused_fd(fd)) is called only when file descriptors are used in the event metadata (metadata->fd is set). This is default mode of event reporting. There's another mode (fid mode) enabled by FAN_REPORT_FID, FAN_REPORT_DIR_FID flags in fanotify_init(). In this mode file descriptors are not used and metadata->fd is always set to FAN_NOFD. In this mode in addition to default metadata, additional struct's are sent to a user. That's what those two if() cases do (lines 468 - 528). Therefore, in default mode file descriptors are created and copy_info_to_user() is not called, and in fid mode file descriptors are not created and copy_info_to_user() is called.

Edited by Andrey Albershteyn

Merge request reports