fuse_dev_ioctl(): switch to fdget()
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 21 Aug 2022 18:02:15 +0000 (14:02 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 21 Apr 2023 02:55:35 +0000 (22:55 -0400)
Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/fuse/dev.c

index eb4f88e..1a8f82f 100644 (file)
@@ -2257,30 +2257,31 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
        int res;
        int oldfd;
        struct fuse_dev *fud = NULL;
+       struct fd f;
 
        switch (cmd) {
        case FUSE_DEV_IOC_CLONE:
-               res = -EFAULT;
-               if (!get_user(oldfd, (__u32 __user *)arg)) {
-                       struct file *old = fget(oldfd);
-
-                       res = -EINVAL;
-                       if (old) {
-                               /*
-                                * Check against file->f_op because CUSE
-                                * uses the same ioctl handler.
-                                */
-                               if (old->f_op == file->f_op)
-                                       fud = fuse_get_dev(old);
-
-                               if (fud) {
-                                       mutex_lock(&fuse_mutex);
-                                       res = fuse_device_clone(fud->fc, file);
-                                       mutex_unlock(&fuse_mutex);
-                               }
-                               fput(old);
-                       }
+               if (get_user(oldfd, (__u32 __user *)arg))
+                       return -EFAULT;
+
+               f = fdget(oldfd);
+               if (!f.file)
+                       return -EINVAL;
+
+               /*
+                * Check against file->f_op because CUSE
+                * uses the same ioctl handler.
+                */
+               if (f.file->f_op == file->f_op)
+                       fud = fuse_get_dev(f.file);
+
+               res = -EINVAL;
+               if (fud) {
+                       mutex_lock(&fuse_mutex);
+                       res = fuse_device_clone(fud->fc, file);
+                       mutex_unlock(&fuse_mutex);
                }
+               fdput(f);
                break;
        default:
                res = -ENOTTY;