fhandle: hoist copy_from_user() above get_path_from_fd()
authorChristian Brauner <brauner@kernel.org>
Tue, 24 Jun 2025 08:29:05 +0000 (10:29 +0200)
committerChristian Brauner <brauner@kernel.org>
Tue, 24 Jun 2025 11:00:09 +0000 (13:00 +0200)
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>
fs/fhandle.c

index 66ff60591d17b29200ec9d0ac74daeb013d4db52..73f56f8e7d5dc94e15c07509ffe01340862d03d9 100644 (file)
@@ -323,13 +323,24 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
 {
        int retval = 0;
        struct file_handle f_handle;
-       struct file_handle *handle = NULL;
+       struct file_handle *handle __free(kfree) = NULL;
        struct handle_to_path_ctx ctx = {};
        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);
        if (retval)
-               goto out_err;
+               return retval;
 
        eops = ctx.root.mnt->mnt_sb->s_export_op;
        if (eops && eops->permission)
@@ -339,21 +350,6 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
        if (retval)
                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),
                         GFP_KERNEL);
        if (!handle) {
@@ -366,7 +362,7 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
                           &ufh->f_handle,
                           f_handle.handle_bytes)) {
                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;
        retval = do_handle_to_path(handle, path, &ctx);
 
-out_handle:
-       kfree(handle);
 out_path:
        path_put(&ctx.root);
-out_err:
        return retval;
 }