fhandle: hoist copy_from_user() above get_path_from_fd()

In follow-up patches we need access to @file_handle->handle_type
before we start caring about get_path_from_fd().

Link: https://lore.kernel.org/20250624-work-pidfs-fhandle-v2-2-d02a04858fe3@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christian Brauner 2025-06-24 10:29:05 +02:00
parent cc678bf7aa
commit 774adcb55f
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
1 changed files with 14 additions and 21 deletions

View File

@ -323,13 +323,24 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
{ {
int retval = 0; int retval = 0;
struct file_handle f_handle; struct file_handle f_handle;
struct file_handle *handle = NULL; struct file_handle *handle __free(kfree) = NULL;
struct handle_to_path_ctx ctx = {}; struct handle_to_path_ctx ctx = {};
const struct export_operations *eops; const struct export_operations *eops;
if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle)))
return -EFAULT;
if ((f_handle.handle_bytes > MAX_HANDLE_SZ) ||
(f_handle.handle_bytes == 0))
return -EINVAL;
if (f_handle.handle_type < 0 ||
FILEID_USER_FLAGS(f_handle.handle_type) & ~FILEID_VALID_USER_FLAGS)
return -EINVAL;
retval = get_path_from_fd(mountdirfd, &ctx.root); retval = get_path_from_fd(mountdirfd, &ctx.root);
if (retval) if (retval)
goto out_err; return retval;
eops = ctx.root.mnt->mnt_sb->s_export_op; eops = ctx.root.mnt->mnt_sb->s_export_op;
if (eops && eops->permission) if (eops && eops->permission)
@ -339,21 +350,6 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
if (retval) if (retval)
goto out_path; goto out_path;
if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) {
retval = -EFAULT;
goto out_path;
}
if ((f_handle.handle_bytes > MAX_HANDLE_SZ) ||
(f_handle.handle_bytes == 0)) {
retval = -EINVAL;
goto out_path;
}
if (f_handle.handle_type < 0 ||
FILEID_USER_FLAGS(f_handle.handle_type) & ~FILEID_VALID_USER_FLAGS) {
retval = -EINVAL;
goto out_path;
}
handle = kmalloc(struct_size(handle, f_handle, f_handle.handle_bytes), handle = kmalloc(struct_size(handle, f_handle, f_handle.handle_bytes),
GFP_KERNEL); GFP_KERNEL);
if (!handle) { if (!handle) {
@ -366,7 +362,7 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
&ufh->f_handle, &ufh->f_handle,
f_handle.handle_bytes)) { f_handle.handle_bytes)) {
retval = -EFAULT; retval = -EFAULT;
goto out_handle; goto out_path;
} }
/* /*
@ -384,11 +380,8 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
handle->handle_type &= ~FILEID_USER_FLAGS_MASK; handle->handle_type &= ~FILEID_USER_FLAGS_MASK;
retval = do_handle_to_path(handle, path, &ctx); retval = do_handle_to_path(handle, path, &ctx);
out_handle:
kfree(handle);
out_path: out_path:
path_put(&ctx.root); path_put(&ctx.root);
out_err:
return retval; return retval;
} }