Commit da6fcc6d authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

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: dfb84c33 ("fuse: allow synchronous FUSE_INIT")
Cc: stable@vger.kernel.org # v6.18
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent aff12041
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -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,