Skip to content

Commit a20853a

Browse files
amir73ilbrauner
authored andcommitted
fs: open_by_handle_at() support for decoding "explicit connectable" file handles
Teach open_by_handle_at(2) about the type format of "explicit connectable" file handles that were created using the AT_HANDLE_CONNECTABLE flag to name_to_handle_at(2). When decoding an "explicit connectable" file handles, name_to_handle_at(2) should fail if it cannot open a "connected" fd with known path, which is accessible (to capable user) from mount fd path. Note that this does not check if the path is accessible to the calling user, just that it is accessible wrt the mount namesapce, so if there is no "connected" alias, or if parts of the path are hidden in the mount namespace, open_by_handle_at(2) will return -ESTALE. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Link: https://lore.kernel.org/r/20241011090023.655623-4-amir73il@gmail.com Fixes: 570df4e ("ceph: snapshot nfs re-export") Acked-by: Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent c374196 commit a20853a

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

fs/fhandle.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,13 @@ static int vfs_dentry_acceptable(void *context, struct dentry *dentry)
246246

247247
if (!(ctx->flags & HANDLE_CHECK_SUBTREE) || d == root)
248248
retval = 1;
249-
WARN_ON_ONCE(d != root && d != root->d_sb->s_root);
249+
/*
250+
* exportfs_decode_fh_raw() does not call acceptable() callback with
251+
* a disconnected directory dentry, so we should have reached either
252+
* mount fd directory or sb root.
253+
*/
254+
if (ctx->fh_flags & EXPORT_FH_DIR_ONLY)
255+
WARN_ON_ONCE(d != root && d != root->d_sb->s_root);
250256
dput(d);
251257
return retval;
252258
}
@@ -350,6 +356,7 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
350356
retval = -EINVAL;
351357
goto out_path;
352358
}
359+
353360
handle = kmalloc(struct_size(handle, f_handle, f_handle.handle_bytes),
354361
GFP_KERNEL);
355362
if (!handle) {
@@ -365,6 +372,17 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
365372
goto out_handle;
366373
}
367374

375+
/*
376+
* If handle was encoded with AT_HANDLE_CONNECTABLE, verify that we
377+
* are decoding an fd with connected path, which is accessible from
378+
* the mount fd path.
379+
*/
380+
if (f_handle.handle_type & FILEID_IS_CONNECTABLE) {
381+
ctx.fh_flags |= EXPORT_FH_CONNECTABLE;
382+
ctx.flags |= HANDLE_CHECK_SUBTREE;
383+
}
384+
if (f_handle.handle_type & FILEID_IS_DIR)
385+
ctx.fh_flags |= EXPORT_FH_DIR_ONLY;
368386
/* Filesystem code should not be exposed to user flags */
369387
handle->handle_type &= ~FILEID_USER_FLAGS_MASK;
370388
retval = do_handle_to_path(handle, path, &ctx);

include/linux/exportfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ struct fid {
171171
/* Flags supported in encoded handle_type that is exported to user */
172172
#define FILEID_IS_CONNECTABLE 0x10000
173173
#define FILEID_IS_DIR 0x20000
174-
#define FILEID_VALID_USER_FLAGS (0)
174+
#define FILEID_VALID_USER_FLAGS (FILEID_IS_CONNECTABLE | FILEID_IS_DIR)
175175

176176
/**
177177
* struct export_operations - for nfsd to communicate with file systems

0 commit comments

Comments
 (0)