[PATCH 7.0 19/42] fuse: fuse_dev_ioctl_clone() should wait for device file to be initialized

Greg Kroah-Hartman
2026-04-24T13:32:23Z

From: Miklos Szeredi <mszeredi@redhat.com>

commit da6fcc6dbddbef80e603d2f0c1554a9f2ac03742 upstream.

Use fuse_get_dev() not __fuse_get_dev() on the old fd, since in the case of
synchronous INIT the caller will want to wait for the device file to be
available for cloning, just like I/O wants to wait instead of returning an
error.

Fixes: dfb84c330794 ("fuse: allow synchronous FUSE_INIT")
Cc: stable@vger.kernel.org # v6.18
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/fuse/dev.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)

--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -2599,9 +2599,8 @@ static int fuse_device_clone(struct fuse

static long fuse_dev_ioctl_clone(struct file *file, __u32 __user *argp)
{
- int res;
int oldfd;
- struct fuse_dev *fud = NULL;
+ struct fuse_dev *fud;

if (get_user(oldfd, argp))
return -EFAULT;
@@ -2614,17 +2613,15 @@ static long fuse_dev_ioctl_clone(struct
* Check against file->f_op because CUSE
* uses the same ioctl handler.
*/
- if (fd_file(f)->f_op == file->f_op)
- fud = __fuse_get_dev(fd_file(f));
+ if (fd_file(f)->f_op != file->f_op)
+ return -EINVAL;

- res = -EINVAL;
- if (fud) {
- mutex_lock(&fuse_mutex);
- res = fuse_device_clone(fud->fc, file);
- mutex_unlock(&fuse_mutex);
- }
+ fud = fuse_get_dev(fd_file(f));
+ if (IS_ERR(fud))
+ return PTR_ERR(fud);

- return res;
+ guard(mutex)(&fuse_mutex);
+ return fuse_device_clone(fud->fc, file);
}

static long fuse_dev_ioctl_backing_open(struct file *file,