From 2f02fd3fa13e51713b630164f8a8e5b42de8283b Mon Sep 17 00:00:00 2001
From: Amir Goldstein <amir73il@gmail.com>
Date: Sun, 24 May 2020 10:24:41 +0300
Subject: [PATCH] fanotify: fix ignore mask logic for events on child and on
dir
Git-commit: 2f02fd3fa13e51713b630164f8a8e5b42de8283b
Patch-mainline: v5.7-rc1
References: bsc#1172719
The comments in fanotify_group_event_mask() say:
"If the event is on dir/child and this mark doesn't care about
events on dir/child, don't send it!"
Specifically, mount and filesystem marks do not care about events
on child, but they can still specify an ignore mask for those events.
For example, a group that has:
- A mount mark with mask 0 and ignore_mask FAN_OPEN
- An inode mark on a directory with mask FAN_OPEN | FAN_OPEN_EXEC
with flag FAN_EVENT_ON_CHILD
A child file open for exec would be reported to group with the FAN_OPEN
event despite the fact that FAN_OPEN is in ignore mask of mount mark,
because the mark iteration loop skips over non-inode marks for events
on child when calculating the ignore mask.
Move ignore mask calculation to the top of the iteration loop block
before excluding marks for events on dir/child.
Link: https://lore.kernel.org/r/20200524072441.18258-1-amir73il@gmail.com
Reported-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/linux-fsdevel/20200521162443.GA26052@quack2.suse.cz/
Fixes: 55bf882c7f13 "fanotify: fix merging marks masks with FAN_ONDIR"
Fixes: b469e7e47c8a "fanotify: fix handling of events on child..."
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
fs/notify/fanotify/fanotify.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -111,11 +111,12 @@ static bool fanotify_should_send_event(s
* If the event is on dir and this mark doesn't care about
* events on dir, don't send it!
*/
- if (inode_mark &&
- (!(event_mask & FS_EVENT_ON_CHILD) ||
- (inode_mark->mask & FS_EVENT_ON_CHILD)) &&
- (!(event_mask & FS_ISDIR) || inode_mark->mask & FS_ISDIR)) {
- marks_mask |= inode_mark->mask;
+ if (inode_mark) {
+ if ((!(event_mask & FS_EVENT_ON_CHILD) ||
+ (inode_mark->mask & FS_EVENT_ON_CHILD)) &&
+ (!(event_mask & FS_ISDIR) || inode_mark->mask & FS_ISDIR))
+ marks_mask |= inode_mark->mask;
+ /* Apply ignore mask regardless of ISDIR and ON_CHILD flags */
marks_ignored_mask |= inode_mark->ignored_mask;
}
@@ -125,9 +126,11 @@ static bool fanotify_should_send_event(s
* If the event is on dir and this mark doesn't care about
* events on dir, don't send it!
*/
- if (vfsmnt_mark && !(event_mask & FS_EVENT_ON_CHILD) &&
- (!(event_mask & FS_ISDIR) || vfsmnt_mark->mask & FS_ISDIR)) {
- marks_mask |= vfsmnt_mark->mask;
+ if (vfsmnt_mark) {
+ if (!(event_mask & FS_EVENT_ON_CHILD) &&
+ (!(event_mask & FS_ISDIR) || vfsmnt_mark->mask & FS_ISDIR))
+ marks_mask |= vfsmnt_mark->mask;
+ /* Apply ignore mask regardless of ISDIR and ON_CHILD flags */
marks_ignored_mask |= vfsmnt_mark->ignored_mask;
}