From: Miklos Szeredi Date: Thu, 2 Apr 2026 18:19:55 +0000 (+0200) Subject: fuse: fuse_dev_ioctl_clone() should wait for device file to be initialized X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=da6fcc6dbddbef80e603d2f0c1554a9f2ac03742;p=thirdparty%2Flinux.git fuse: fuse_dev_ioctl_clone() should wait for device file to be initialized 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 --- diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index b212565a78cf4..8d5bab05adf49 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -2597,9 +2597,8 @@ static int fuse_device_clone(struct fuse_conn *fc, struct file *new) 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; @@ -2612,17 +2611,15 @@ static long fuse_dev_ioctl_clone(struct file *file, __u32 __user *argp) * 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,