Message ID | 20220128195656.GA26981@kili (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | fanotify: Fix stale file descriptor in copy_event_to_user() | expand |
On Fri 28-01-22 22:57:01, Dan Carpenter wrote: > 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: f644bc449b37 ("fanotify: fix copy_event_to_user() fid error clean up") > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> > Reviewed-by: Mathias Krause <minipli@grsecurity.net> Thanks. I've added the patch to my tree and will push it to Linus. Honza > --- > fs/notify/fanotify/fanotify_user.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c > index 1026f67b1d1e..2ff6bd85ba8f 100644 > --- a/fs/notify/fanotify/fanotify_user.c > +++ b/fs/notify/fanotify/fanotify_user.c > @@ -701,9 +701,6 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, > if (fanotify_is_perm_event(event->mask)) > FANOTIFY_PERM(event)->fd = fd; > > - if (f) > - fd_install(fd, f); > - > if (info_mode) { > ret = copy_info_records_to_user(event, info, info_mode, pidfd, > buf, count); > @@ -711,6 +708,9 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, > goto out_close_fd; > } > > + if (f) > + fd_install(fd, f); > + > return metadata.event_len; > > out_close_fd: > -- > 2.20.1 >
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 1026f67b1d1e..2ff6bd85ba8f 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -701,9 +701,6 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, if (fanotify_is_perm_event(event->mask)) FANOTIFY_PERM(event)->fd = fd; - if (f) - fd_install(fd, f); - if (info_mode) { ret = copy_info_records_to_user(event, info, info_mode, pidfd, buf, count); @@ -711,6 +708,9 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, goto out_close_fd; } + if (f) + fd_install(fd, f); + return metadata.event_len; out_close_fd: