All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: Matthew Bobrowski <mbobrowski@mbobrowski.org>,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH v2 7/9] fanotify: record either old name new name or both for FAN_RENAME
Date: Fri, 19 Nov 2021 09:17:36 +0200	[thread overview]
Message-ID: <20211119071738.1348957-8-amir73il@gmail.com> (raw)
In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com>

We do not want to report the dirfid+name of a directory whose
inode/sb are not watched, because watcher may not have permissions
to see the directory content.

The FAN_MOVED_FROM/TO flags are used internally to indicate to
fanotify_alloc_event() if we need to record only the old parent+name,
only the new parent+name or both.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.c | 57 ++++++++++++++++++++++++++++++-----
 1 file changed, 50 insertions(+), 7 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 018b32a57702..c0a3fb1dd066 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -290,6 +290,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
 	__u32 marks_mask = 0, marks_ignored_mask = 0;
 	__u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS |
 				     FANOTIFY_EVENT_FLAGS;
+	__u32 moved_mask = 0;
 	const struct path *path = fsnotify_data_path(data, data_type);
 	unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
 	struct fsnotify_mark *mark;
@@ -327,17 +328,44 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
 			continue;
 
 		/*
-		 * If the event is on a child and this mark is on a parent not
-		 * watching children, don't send it!
+		 * In the special case of FAN_RENAME event, inode mark is the
+		 * mark on the old dir and parent mark is the mark on the new
+		 * dir.  We do not want to report the dirfid+name of a directory
+		 * whose inode/sb are not watched.  The FAN_MOVE flags
+		 * are used internally to indicate if we need to report only
+		 * the old parent+name, only the new parent+name or both.
 		 */
-		if (type == FSNOTIFY_OBJ_TYPE_PARENT &&
-		    !(mark->mask & FS_EVENT_ON_CHILD))
+		if (event_mask & FAN_RENAME) {
+			/* Old dir sb are watched - report old info */
+			if (type != FSNOTIFY_OBJ_TYPE_PARENT &&
+			    (mark->mask & FAN_RENAME))
+				moved_mask |= FAN_MOVED_FROM;
+			/* New dir sb are watched - report new info */
+			if (type != FSNOTIFY_OBJ_TYPE_INODE &&
+			    (mark->mask & FAN_RENAME))
+				moved_mask |= FAN_MOVED_TO;
+		} else if (type == FSNOTIFY_OBJ_TYPE_PARENT &&
+			   !(mark->mask & FS_EVENT_ON_CHILD)) {
+			/*
+			 * If the event is on a child and this mark is on
+			 * a parent not watching children, don't send it!
+			 */
 			continue;
+		}
 
 		marks_mask |= mark->mask;
 	}
 
 	test_mask = event_mask & marks_mask & ~marks_ignored_mask;
+	/*
+	 * Add the internal FAN_MOVE flags to FAN_RENAME event.
+	 * They will not be reported to user along with FAN_RENAME.
+	 */
+	if (test_mask & FAN_RENAME) {
+		if (WARN_ON_ONCE(test_mask & FAN_MOVE))
+			return 0;
+		test_mask |= moved_mask;
+	}
 
 	/*
 	 * For dirent modification events (create/delete/move) that do not carry
@@ -753,13 +781,28 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
 		}
 
 		/*
-		 * In the special case of FAN_RENAME event, we record both
-		 * old and new parent+name.
+		 * In the special case of FAN_RENAME event, the FAN_MOVE flags
+		 * are only used internally to indicate if we need to report
+		 * only the old parent+name, only the new parent+name or both.
 		 * 'dirid' and 'file_name' are the old parent+name and
 		 * 'moved' has the new parent+name.
 		 */
 		if (mask & FAN_RENAME) {
-			moved = fsnotify_data_dentry(data, data_type);
+			/* Either old and/or new info must be reported */
+			if (WARN_ON_ONCE(!(mask & FAN_MOVE)))
+				return NULL;
+
+			if (!(mask & FAN_MOVED_FROM)) {
+				/* Do not report old parent+name */
+				dirid = NULL;
+				file_name = NULL;
+			}
+			if (mask & FAN_MOVED_TO) {
+				/* Report new parent+name */
+				moved = fsnotify_data_dentry(data, data_type);
+			}
+			/* Clear internal flags */
+			mask &= ~FAN_MOVE;
 			name_event = true;
 		}
 	}
-- 
2.33.1


  parent reply	other threads:[~2021-11-19  7:17 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-19  7:17 [PATCH v2 0/9] Extend fanotify dirent events Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 1/9] fanotify: introduce group flag FAN_REPORT_TARGET_FID Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 2/9] fsnotify: generate FS_RENAME event with rich information Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 3/9] fanotify: use macros to get the offset to fanotify_info buffer Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 4/9] fanotify: use helpers to parcel " Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 5/9] fanotify: support secondary dir fh and name in fanotify_info Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 6/9] fanotify: record old and new parent and name in FAN_RENAME event Amir Goldstein
2021-11-26 14:44   ` Jan Kara
2021-11-19  7:17 ` Amir Goldstein [this message]
2021-11-26 15:14   ` [PATCH v2 7/9] fanotify: record either old name new name or both for FAN_RENAME Jan Kara
2021-11-29 19:15     ` Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 8/9] fanotify: report old and/or new parent+name in FAN_RENAME event Amir Goldstein
2021-11-19  7:17 ` [PATCH v2 9/9] fanotify: wire up " Amir Goldstein
2021-11-20 12:59 ` [PATCH v2 0/9] Extend fanotify dirent events Amir Goldstein
2021-11-26 15:28 ` Jan Kara
2021-11-29 19:12   ` Amir Goldstein

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211119071738.1348957-8-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=mbobrowski@mbobrowski.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.