summaryrefslogtreecommitdiffstats
path: root/fs/notify/fanotify/fanotify_user.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2020-07-16 10:42:15 +0200
committerJan Kara <jack@suse.cz>2020-07-27 21:23:37 +0200
commit85af5d9258cc5862167c578c63c65ac700a3fa19 (patch)
tree1e1fa02661ff1fb256add181ddfb6a2862fd5e59 /fs/notify/fanotify/fanotify_user.c
parentfanotify: prepare for implicit event flags in mark mask (diff)
downloadlinux-85af5d9258cc5862167c578c63c65ac700a3fa19.tar.xz
linux-85af5d9258cc5862167c578c63c65ac700a3fa19.zip
fanotify: use FAN_EVENT_ON_CHILD as implicit flag on sb/mount/non-dir marks
Up to now, fanotify allowed to set the FAN_EVENT_ON_CHILD flag on sb/mount marks and non-directory inode mask, but the flag was ignored. Mask out the flag if it is provided by user on sb/mount/non-dir marks and define it as an implicit flag that cannot be removed by user. This flag is going to be used internally to request for events with parent and name info. Link: https://lore.kernel.org/r/20200716084230.30611-8-amir73il@gmail.com Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify/fanotify/fanotify_user.c')
-rw-r--r--fs/notify/fanotify/fanotify_user.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index ab974cd234f7..16d70a8e90f9 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -1050,6 +1050,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
bool ignored = flags & FAN_MARK_IGNORED_MASK;
unsigned int obj_type, fid_mode;
+ u32 umask = 0;
int ret;
pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n",
@@ -1167,6 +1168,12 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
else
mnt = path.mnt;
+ /* Mask out FAN_EVENT_ON_CHILD flag for sb/mount/non-dir marks */
+ if (mnt || !S_ISDIR(inode->i_mode)) {
+ mask &= ~FAN_EVENT_ON_CHILD;
+ umask = FAN_EVENT_ON_CHILD;
+ }
+
/* create/update an inode mark */
switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
case FAN_MARK_ADD:
@@ -1183,13 +1190,13 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
case FAN_MARK_REMOVE:
if (mark_type == FAN_MARK_MOUNT)
ret = fanotify_remove_vfsmount_mark(group, mnt, mask,
- flags, 0);
+ flags, umask);
else if (mark_type == FAN_MARK_FILESYSTEM)
ret = fanotify_remove_sb_mark(group, mnt->mnt_sb, mask,
- flags, 0);
+ flags, umask);
else
ret = fanotify_remove_inode_mark(group, inode, mask,
- flags, 0);
+ flags, umask);
break;
default:
ret = -EINVAL;