aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/notify/fanotify/fanotify_user.c25
-rw-r--r--include/linux/fanotify.h11
2 files changed, 34 insertions, 2 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index bbcb98e..1c09e63 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -664,6 +664,20 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
init_waitqueue_head(&group->fanotify_data.access_waitq);
INIT_LIST_HEAD(&group->fanotify_data.access_list);
#endif
+ switch (flags & FAN_ALL_CLASS_BITS) {
+ case FAN_CLASS_NOTIF:
+ group->priority = FS_PRIO_0;
+ break;
+ case FAN_CLASS_CONTENT:
+ group->priority = FS_PRIO_1;
+ break;
+ case FAN_CLASS_PRE_CONTENT:
+ group->priority = FS_PRIO_2;
+ break;
+ default:
+ fd = -EINVAL;
+ goto out_put_group;
+ }
fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
if (fd < 0)
@@ -719,6 +733,16 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
ret = -EINVAL;
if (unlikely(filp->f_op != &fanotify_fops))
goto fput_and_out;
+ group = filp->private_data;
+
+ /*
+ * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not
+ * allowed to set permissions events.
+ */
+ ret = -EINVAL;
+ if (mask & FAN_ALL_PERM_EVENTS &&
+ group->priority == FS_PRIO_0)
+ goto fput_and_out;
ret = fanotify_find_path(dfd, pathname, &path, flags);
if (ret)
@@ -729,7 +753,6 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
inode = path.dentry->d_inode;
else
mnt = path.mnt;
- group = filp->private_data;
/* create/update an inode mark */
switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 63531a6..2c89ce7 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -25,7 +25,16 @@
#define FAN_CLOEXEC 0x00000001
#define FAN_NONBLOCK 0x00000002
-#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK)
+/* These are NOT bitwise flags. Both bits are used togther. */
+#define FAN_CLASS_NOTIF 0x00000000
+#define FAN_CLASS_CONTENT 0x00000004
+#define FAN_CLASS_PRE_CONTENT 0x00000008
+
+#define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
+ FAN_CLASS_PRE_CONTENT)
+
+#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \
+ FAN_ALL_CLASS_BITS)
/* flags used for fanotify_modify_mark() */
#define FAN_MARK_ADD 0x00000001