Thread (39 messages) 39 messages, 4 authors, 2021-08-05

Re: [PATCH v5 14/23] fanotify: Encode invalid file handler when no inode is provided

From: Jan Kara <jack@suse.cz>
Date: 2021-08-05 09:56:21
Also in: linux-api, linux-fsdevel

On Wed 04-08-21 12:06:03, Gabriel Krisman Bertazi wrote:
Instead of failing, encode an invalid file handler in fanotify_encode_fh
if no inode is provided.  This bogus file handler will be reported by
FAN_FS_ERROR for non-inode errors.

Also adjust the single caller that might rely on failure after passing
an empty inode.
It is not 'file handler' but rather 'file handle' - several times in the
changelog and in subject :).
quoted hunk ↗ jump to hunk
Suggested-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Gabriel Krisman Bertazi <redacted>
---
 fs/notify/fanotify/fanotify.c | 39 ++++++++++++++++++++---------------
 fs/notify/fanotify/fanotify.h |  6 ++++--
 2 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 0d6ba218bc01..456c60107d88 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -349,12 +349,6 @@ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode,
 	void *buf = fh->buf;
 	int err;
 
-	fh->type = FILEID_ROOT;
-	fh->len = 0;
-	fh->flags = 0;
-	if (!inode)
-		return 0;
-
I'd keep the fh->flags initialization here. Otherwise it will not be
initialized on some error returns.
quoted hunk ↗ jump to hunk
@@ -363,8 +357,9 @@ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode,
 	if (fh_len < 4 || WARN_ON_ONCE(fh_len % 4))
 		goto out_err;
 
-	/* No external buffer in a variable size allocated fh */
-	if (gfp && fh_len > FANOTIFY_INLINE_FH_LEN) {
+	fh->flags = 0;
+	/* No external buffer in a variable size allocated fh or null fh */
+	if (inode && gfp && fh_len > FANOTIFY_INLINE_FH_LEN) {
 		/* Treat failure to allocate fh as failure to encode fh */
 		err = -ENOMEM;
 		ext_buf = kmalloc(fh_len, gfp);
@@ -376,14 +371,24 @@ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode,
 		fh->flags |= FANOTIFY_FH_FLAG_EXT_BUF;
 	}
 
-	dwords = fh_len >> 2;
-	type = exportfs_encode_inode_fh(inode, buf, &dwords, NULL);
-	err = -EINVAL;
-	if (!type || type == FILEID_INVALID || fh_len != dwords << 2)
-		goto out_err;
-
-	fh->type = type;
-	fh->len = fh_len;
+	if (inode) {
+		dwords = fh_len >> 2;
+		type = exportfs_encode_inode_fh(inode, buf, &dwords, NULL);
+		err = -EINVAL;
+		if (!type || type == FILEID_INVALID || fh_len != dwords << 2)
+			goto out_err;
+		fh->type = type;
+		fh->len = fh_len;
+	} else {
+		/*
+		 * Invalid FHs are used on FAN_FS_ERROR for errors not
+		 * linked to any inode. Caller needs to guarantee the fh
+		 * has at least FANOTIFY_NULL_FH_LEN bytes of space.
+		 */
+		fh->type = FILEID_INVALID;
+		fh->len = FANOTIFY_NULL_FH_LEN;
+		memset(buf, 0, FANOTIFY_NULL_FH_LEN);
+	}
Maybe it will become clearer later during the series but why do you set
fh->len to FANOTIFY_NULL_FH_LEN and not 0?

								Honza
-- 
Jan Kara [off-list ref]
SUSE Labs, CR
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help