History

Merge tag 'fsnotify_for_v6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull fsnotify updates from Jan Kara: "A couple of smaller random fsnotify fixes" * tag 'fsnotify_for_v6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fsnotify: Fix ordering of iput() and watched_objects decrement fsnotify: fix sending inotify event with unexpected filename fanotify: allow reporting errors on failure to open fd fsnotify, lsm: Decouple fsnotify from lsm

Linus Torvalds committed 1 year ago

Commit 2dde2632 parents c01f664 21d1b618 files · +77 −59Browse files

Unified · Split

8 files
  1. fs/notify/fanotify/Kconfig +0 −1
  2. fs/notify/fanotify/fanotify_user.c +48 −37
  3. fs/notify/fsnotify.c +13 −10
  4. fs/notify/mark.c +9 −3
  5. fs/open.c +4 −0
  6. include/linux/fanotify.h +1 −0
  7. include/uapi/linux/fanotify.h +1 −0
  8. security/security.c +1 −8
fs/notify/fanotify/Kconfig+0−1
@@ -15,7 +15,6 @@ config FANOTIFY · 14 unmodified lines
15config FANOTIFY_ACCESS_PERMISSIONS15config FANOTIFY_ACCESS_PERMISSIONS
16 bool "fanotify permissions checking"16 bool "fanotify permissions checking"
17 depends on FANOTIFY17 depends on FANOTIFY
18 depends on SECURITY
19 default n18 default n
20 help19 help
21 Say Y here is you want fanotify listeners to be able to make permissions20 Say Y here is you want fanotify listeners to be able to make permissions
fs/notify/fanotify/fanotify_user.c+48−37
@@ -265,13 +265,6 @@ static int create_fd(struct fsnotify_group *group, const struct path *path, · 264 unmodified lines
265 group->fanotify_data.f_flags | __FMODE_NONOTIFY,265 group->fanotify_data.f_flags | __FMODE_NONOTIFY,
266 current_cred());266 current_cred());
267 if (IS_ERR(new_file)) {267 if (IS_ERR(new_file)) {
268 /*
269 * we still send an event even if we can't open the file. this
270 * can happen when say tasks are gone and we try to open their
271 * /proc files or we try to open a WRONLY file like in sysfs
272 * we just send the errno to userspace since there isn't much
273 * else we can do.
274 */
275 put_unused_fd(client_fd);268 put_unused_fd(client_fd);
276 client_fd = PTR_ERR(new_file);269 client_fd = PTR_ERR(new_file);
277 } else {270 } else {
@@ -662,7 +655,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 384 unmodified lines
662 unsigned int info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES);655 unsigned int info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES);
663 unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD;656 unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD;
664 struct file *f = NULL, *pidfd_file = NULL;657 struct file *f = NULL, *pidfd_file = NULL;
665 int ret, pidfd = FAN_NOPIDFD, fd = FAN_NOFD;658 int ret, pidfd = -ESRCH, fd = -EBADF;
666 659
667 pr_debug("%s: group=%p event=%p\n", __func__, group, event);660 pr_debug("%s: group=%p event=%p\n", __func__, group, event);
668 661
@@ -690,10 +683,39 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 21 unmodified lines
690 if (!FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV) &&683 if (!FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV) &&
691 path && path->mnt && path->dentry) {684 path && path->mnt && path->dentry) {
692 fd = create_fd(group, path, &f);685 fd = create_fd(group, path, &f);
693 if (fd < 0)686 /*
694 return fd;687 * Opening an fd from dentry can fail for several reasons.
688 * For example, when tasks are gone and we try to open their
689 * /proc files or we try to open a WRONLY file like in sysfs
690 * or when trying to open a file that was deleted on the
691 * remote network server.
692 *
693 * For a group with FAN_REPORT_FD_ERROR, we will send the
694 * event with the error instead of the open fd, otherwise
695 * Userspace may not get the error at all.
696 * In any case, userspace will not know which file failed to
697 * open, so add a debug print for further investigation.
698 */
699 if (fd < 0) {
700 pr_debug("fanotify: create_fd(%pd2) failed err=%d\n",
701 path->dentry, fd);
702 if (!FAN_GROUP_FLAG(group, FAN_REPORT_FD_ERROR)) {
703 /*
704 * Historically, we've handled EOPENSTALE in a
705 * special way and silently dropped such
706 * events. Now we have to keep it to maintain
707 * backward compatibility...
708 */
709 if (fd == -EOPENSTALE)
710 fd = 0;
711 return fd;
712 }
713 }
695 }714 }
696 metadata.fd = fd;715 if (FAN_GROUP_FLAG(group, FAN_REPORT_FD_ERROR))
716 metadata.fd = fd;
717 else
718 metadata.fd = fd >= 0 ? fd : FAN_NOFD;
697 719
698 if (pidfd_mode) {720 if (pidfd_mode) {
699 /*721 /*
@@ -708,18 +730,16 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 8 unmodified lines
708 * The PIDTYPE_TGID check for an event->pid is performed730 * The PIDTYPE_TGID check for an event->pid is performed
709 * preemptively in an attempt to catch out cases where the event731 * preemptively in an attempt to catch out cases where the event
710 * listener reads events after the event generating process has732 * listener reads events after the event generating process has
711 * already terminated. Report FAN_NOPIDFD to the event listener733 * already terminated. Depending on flag FAN_REPORT_FD_ERROR,
712 * in those cases, with all other pidfd creation errors being734 * report either -ESRCH or FAN_NOPIDFD to the event listener in
713 * reported as FAN_EPIDFD.735 * those cases with all other pidfd creation errors reported as
736 * the error code itself or as FAN_EPIDFD.
714 */737 */
715 if (metadata.pid == 0 ||738 if (metadata.pid && pid_has_task(event->pid, PIDTYPE_TGID))
716 !pid_has_task(event->pid, PIDTYPE_TGID)) {
717 pidfd = FAN_NOPIDFD;
718 } else {
719 pidfd = pidfd_prepare(event->pid, 0, &pidfd_file);739 pidfd = pidfd_prepare(event->pid, 0, &pidfd_file);
720 if (pidfd < 0)740
721 pidfd = FAN_EPIDFD;741 if (!FAN_GROUP_FLAG(group, FAN_REPORT_FD_ERROR) && pidfd < 0)
722 }742 pidfd = pidfd == -ESRCH ? FAN_NOPIDFD : FAN_EPIDFD;
723 }743 }
724 744
725 ret = -EFAULT;745 ret = -EFAULT;
@@ -736,9 +756,6 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 10 unmodified lines
736 buf += FAN_EVENT_METADATA_LEN;756 buf += FAN_EVENT_METADATA_LEN;
737 count -= FAN_EVENT_METADATA_LEN;757 count -= FAN_EVENT_METADATA_LEN;
738 758
739 if (fanotify_is_perm_event(event->mask))
740 FANOTIFY_PERM(event)->fd = fd;
741
742 if (info_mode) {759 if (info_mode) {
743 ret = copy_info_records_to_user(event, info, info_mode, pidfd,760 ret = copy_info_records_to_user(event, info, info_mode, pidfd,
744 buf, count);761 buf, count);
@@ -752,15 +769,18 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 7 unmodified lines
752 if (pidfd_file)769 if (pidfd_file)
753 fd_install(pidfd, pidfd_file);770 fd_install(pidfd, pidfd_file);
754 771
772 if (fanotify_is_perm_event(event->mask))
773 FANOTIFY_PERM(event)->fd = fd;
774
755 return metadata.event_len;775 return metadata.event_len;
756 776
757out_close_fd:777out_close_fd:
758 if (fd != FAN_NOFD) {778 if (f) {
759 put_unused_fd(fd);779 put_unused_fd(fd);
760 fput(f);780 fput(f);
761 }781 }
762 782
763 if (pidfd >= 0) {783 if (pidfd_file) {
764 put_unused_fd(pidfd);784 put_unused_fd(pidfd);
765 fput(pidfd_file);785 fput(pidfd_file);
766 }786 }
@@ -827,15 +847,6 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, · 60 unmodified lines
827 }847 }
828 848
829 ret = copy_event_to_user(group, event, buf, count);849 ret = copy_event_to_user(group, event, buf, count);
830 if (unlikely(ret == -EOPENSTALE)) {
831 /*
832 * We cannot report events with stale fd so drop it.
833 * Setting ret to 0 will continue the event loop and
834 * do the right thing if there are no more events to
835 * read (i.e. return bytes read, -EAGAIN or wait).
836 */
837 ret = 0;
838 }
839 850
840 /*851 /*
841 * Permission events get queued to wait for response. Other852 * Permission events get queued to wait for response. Other
@@ -844,7 +855,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, · 2 unmodified lines
844 if (!fanotify_is_perm_event(event->mask)) {855 if (!fanotify_is_perm_event(event->mask)) {
845 fsnotify_destroy_event(group, &event->fse);856 fsnotify_destroy_event(group, &event->fse);
846 } else {857 } else {
847 if (ret <= 0) {858 if (ret <= 0 || FANOTIFY_PERM(event)->fd < 0) {
848 spin_lock(&group->notification_lock);859 spin_lock(&group->notification_lock);
849 finish_permission_event(group,860 finish_permission_event(group,
850 FANOTIFY_PERM(event), FAN_DENY, NULL);861 FANOTIFY_PERM(event), FAN_DENY, NULL);
@@ -1941,7 +1952,7 @@ static int __init fanotify_user_setup(void) · 1090 unmodified lines
1941 FANOTIFY_DEFAULT_MAX_USER_MARKS);1952 FANOTIFY_DEFAULT_MAX_USER_MARKS);
1942 1953
1943 BUILD_BUG_ON(FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS);1954 BUILD_BUG_ON(FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS);
1944 BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 12);1955 BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 13);
1945 BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 11);1956 BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 11);
1946 1957
1947 fanotify_mark_cache = KMEM_CACHE(fanotify_mark,1958 fanotify_mark_cache = KMEM_CACHE(fanotify_mark,
fs/notify/fsnotify.c+13−10
@@ -333,16 +333,19 @@ static int fsnotify_handle_event(struct fsnotify_group *group, __u32 mask, · 332 unmodified lines
333 if (!inode_mark)333 if (!inode_mark)
334 return 0;334 return 0;
335 335
336 if (mask & FS_EVENT_ON_CHILD) {336 /*
337 /*337 * Some events can be sent on both parent dir and child marks (e.g.
338 * Some events can be sent on both parent dir and child marks338 * FS_ATTRIB). If both parent dir and child are watching, report the
339 * (e.g. FS_ATTRIB). If both parent dir and child are339 * event once to parent dir with name (if interested) and once to child
340 * watching, report the event once to parent dir with name (if340 * without name (if interested).
341 * interested) and once to child without name (if interested).341 *
342 * The child watcher is expecting an event without a file name342 * In any case regardless whether the parent is watching or not, the
343 * and without the FS_EVENT_ON_CHILD flag.343 * child watcher is expecting an event without the FS_EVENT_ON_CHILD
344 */344 * flag. The file name is expected if and only if this is a directory
345 mask &= ~FS_EVENT_ON_CHILD;345 * event.
346 */
347 mask &= ~FS_EVENT_ON_CHILD;
348 if (!(mask & ALL_FSNOTIFY_DIRENT_EVENTS)) {
346 dir = NULL;349 dir = NULL;
347 name = NULL;350 name = NULL;
348 }351 }
fs/notify/mark.c+9−3
@@ -138,8 +138,11 @@ static void fsnotify_get_sb_watched_objects(struct super_block *sb) · 137 unmodified lines
138 138
139static void fsnotify_put_sb_watched_objects(struct super_block *sb)139static void fsnotify_put_sb_watched_objects(struct super_block *sb)
140{140{
141 if (atomic_long_dec_and_test(fsnotify_sb_watched_objects(sb)))141 atomic_long_t *watched_objects = fsnotify_sb_watched_objects(sb);
142 wake_up_var(fsnotify_sb_watched_objects(sb));142
143 /* the superblock can go away after this decrement */
144 if (atomic_long_dec_and_test(watched_objects))
145 wake_up_var(watched_objects);
143}146}
144 147
145static void fsnotify_get_inode_ref(struct inode *inode)148static void fsnotify_get_inode_ref(struct inode *inode)
@@ -150,8 +153,11 @@ static void fsnotify_get_inode_ref(struct inode *inode) · 4 unmodified lines
150 153
151static void fsnotify_put_inode_ref(struct inode *inode)154static void fsnotify_put_inode_ref(struct inode *inode)
152{155{
153 fsnotify_put_sb_watched_objects(inode->i_sb);156 /* read ->i_sb before the inode can go away */
157 struct super_block *sb = inode->i_sb;
158
154 iput(inode);159 iput(inode);
160 fsnotify_put_sb_watched_objects(sb);
155}161}
156 162
157/*163/*
fs/open.c+4−0
@@ -929,6 +929,10 @@ static int do_dentry_open(struct file *f, · 928 unmodified lines
929 if (error)929 if (error)
930 goto cleanup_all;930 goto cleanup_all;
931 931
932 error = fsnotify_open_perm(f);
933 if (error)
934 goto cleanup_all;
935
932 error = break_lease(file_inode(f), f->f_flags);936 error = break_lease(file_inode(f), f->f_flags);
933 if (error)937 if (error)
934 goto cleanup_all;938 goto cleanup_all;
include/linux/fanotify.h+1−0
@@ -36,6 +36,7 @@ · 35 unmodified lines
36#define FANOTIFY_ADMIN_INIT_FLAGS (FANOTIFY_PERM_CLASSES | \36#define FANOTIFY_ADMIN_INIT_FLAGS (FANOTIFY_PERM_CLASSES | \
37 FAN_REPORT_TID | \37 FAN_REPORT_TID | \
38 FAN_REPORT_PIDFD | \38 FAN_REPORT_PIDFD | \
39 FAN_REPORT_FD_ERROR | \
39 FAN_UNLIMITED_QUEUE | \40 FAN_UNLIMITED_QUEUE | \
40 FAN_UNLIMITED_MARKS)41 FAN_UNLIMITED_MARKS)
41 42
include/uapi/linux/fanotify.h+1−0
@@ -60,6 +60,7 @@ · 59 unmodified lines
60#define FAN_REPORT_DIR_FID 0x00000400 /* Report unique directory id */60#define FAN_REPORT_DIR_FID 0x00000400 /* Report unique directory id */
61#define FAN_REPORT_NAME 0x00000800 /* Report events with name */61#define FAN_REPORT_NAME 0x00000800 /* Report events with name */
62#define FAN_REPORT_TARGET_FID 0x00001000 /* Report dirent target id */62#define FAN_REPORT_TARGET_FID 0x00001000 /* Report dirent target id */
63#define FAN_REPORT_FD_ERROR 0x00002000 /* event->fd can report error */
63 64
64/* Convenience macro - FAN_REPORT_NAME requires FAN_REPORT_DIR_FID */65/* Convenience macro - FAN_REPORT_NAME requires FAN_REPORT_DIR_FID */
65#define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)66#define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)
security/security.c+1−8
@@ -19,7 +19,6 @@ · 18 unmodified lines
19#include <linux/kernel.h>19#include <linux/kernel.h>
20#include <linux/kernel_read_file.h>20#include <linux/kernel_read_file.h>
21#include <linux/lsm_hooks.h>21#include <linux/lsm_hooks.h>
22#include <linux/fsnotify.h>
23#include <linux/mman.h>22#include <linux/mman.h>
24#include <linux/mount.h>23#include <linux/mount.h>
25#include <linux/personality.h>24#include <linux/personality.h>
@@ -3103,13 +3102,7 @@ int security_file_receive(struct file *file) · 3077 unmodified lines
3103 */3102 */
3104int security_file_open(struct file *file)3103int security_file_open(struct file *file)
3105{3104{
3106 int ret;3105 return call_int_hook(file_open, file);
3107
3108 ret = call_int_hook(file_open, file);
3109 if (ret)
3110 return ret;
3111
3112 return fsnotify_open_perm(file);
3113}3106}
3114 3107
3115/**3108/**