]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Apr 2018 10:45:16 +0000 (12:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Apr 2018 10:45:16 +0000 (12:45 +0200)
added patches:
fanotify-fix-logic-of-events-on-child.patch

queue-3.18/fanotify-fix-logic-of-events-on-child.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/fanotify-fix-logic-of-events-on-child.patch b/queue-3.18/fanotify-fix-logic-of-events-on-child.patch
new file mode 100644 (file)
index 0000000..9359dbe
--- /dev/null
@@ -0,0 +1,85 @@
+From 54a307ba8d3cd00a3902337ffaae28f436eeb1a4 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Wed, 4 Apr 2018 23:42:18 +0300
+Subject: fanotify: fix logic of events on child
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit 54a307ba8d3cd00a3902337ffaae28f436eeb1a4 upstream.
+
+When event on child inodes are sent to the parent inode mark and
+parent inode mark was not marked with FAN_EVENT_ON_CHILD, the event
+will not be delivered to the listener process. However, if the same
+process also has a mount mark, the event to the parent inode will be
+delivered regadless of the mount mark mask.
+
+This behavior is incorrect in the case where the mount mark mask does
+not contain the specific event type. For example, the process adds
+a mark on a directory with mask FAN_MODIFY (without FAN_EVENT_ON_CHILD)
+and a mount mark with mask FAN_CLOSE_NOWRITE (without FAN_ONDIR).
+
+A modify event on a file inside that directory (and inside that mount)
+should not create a FAN_MODIFY event, because neither of the marks
+requested to get that event on the file.
+
+Fixes: 1968f5eed54c ("fanotify: use both marks when possible")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+[natechancellor: Fix small conflict due to lack of 3cd5eca8d7a2f]
+Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/notify/fanotify/fanotify.c |   34 +++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 19 deletions(-)
+
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -92,7 +92,7 @@ static bool fanotify_should_send_event(s
+                                      u32 event_mask,
+                                      void *data, int data_type)
+ {
+-      __u32 marks_mask, marks_ignored_mask;
++      __u32 marks_mask = 0, marks_ignored_mask = 0;
+       struct path *path = data;
+       pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p"
+@@ -108,24 +108,20 @@ static bool fanotify_should_send_event(s
+           !S_ISDIR(path->dentry->d_inode->i_mode))
+               return false;
+-      if (inode_mark && vfsmnt_mark) {
+-              marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
+-              marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
+-      } else if (inode_mark) {
+-              /*
+-               * if the event is for a child and this inode doesn't care about
+-               * events on the child, don't send it!
+-               */
+-              if ((event_mask & FS_EVENT_ON_CHILD) &&
+-                  !(inode_mark->mask & FS_EVENT_ON_CHILD))
+-                      return false;
+-              marks_mask = inode_mark->mask;
+-              marks_ignored_mask = inode_mark->ignored_mask;
+-      } else if (vfsmnt_mark) {
+-              marks_mask = vfsmnt_mark->mask;
+-              marks_ignored_mask = vfsmnt_mark->ignored_mask;
+-      } else {
+-              BUG();
++      /*
++       * if the event is for a child and this inode doesn't care about
++       * events on the child, don't send it!
++       */
++      if (inode_mark &&
++          (!(event_mask & FS_EVENT_ON_CHILD) ||
++           (inode_mark->mask & FS_EVENT_ON_CHILD))) {
++              marks_mask |= inode_mark->mask;
++              marks_ignored_mask |= inode_mark->ignored_mask;
++      }
++
++      if (vfsmnt_mark) {
++              marks_mask |= vfsmnt_mark->mask;
++              marks_ignored_mask |= vfsmnt_mark->ignored_mask;
+       }
+       if (S_ISDIR(path->dentry->d_inode->i_mode) &&
index 3856b26221239b86acf3bf558605b665914adee5..159f30b7ec5d37a4ac6598ef6e4041c3ec158fa1 100644 (file)
@@ -49,3 +49,4 @@ hypfs_kill_super-deal-with-failed-allocations.patch
 rpc_pipefs-fix-double-dput.patch
 don-t-leak-mnt_internal-away-from-internal-mounts.patch
 autofs-mount-point-create-should-honour-passed-in-mode.patch
+fanotify-fix-logic-of-events-on-child.patch