From: Greg Kroah-Hartman Date: Sun, 22 Apr 2018 10:45:16 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.106~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=97686eefcfef43d6c3a1bd488ac2a884310a7a72;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: fanotify-fix-logic-of-events-on-child.patch --- 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 index 00000000000..9359dbe7291 --- /dev/null +++ b/queue-3.18/fanotify-fix-logic-of-events-on-child.patch @@ -0,0 +1,85 @@ +From 54a307ba8d3cd00a3902337ffaae28f436eeb1a4 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Wed, 4 Apr 2018 23:42:18 +0300 +Subject: fanotify: fix logic of events on child + +From: Amir Goldstein + +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 +Signed-off-by: Amir Goldstein +Signed-off-by: Jan Kara +[natechancellor: Fix small conflict due to lack of 3cd5eca8d7a2f] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + 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) && diff --git a/queue-3.18/series b/queue-3.18/series index 3856b262212..159f30b7ec5 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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