Commit 6a567e92 authored by Miklos Szeredi's avatar Miklos Szeredi

fuse: ioctl: translate ENOSYS in outarg

Fuse shouldn't return ENOSYS from its ioctl implementation. If userspace
responds with ENOSYS it should be translated to ENOTTY.

There are two ways to return an error from the IOCTL request:

 - fuse_out_header.error
 - fuse_ioctl_out.result

Commit 02c0cab8 ("fuse: ioctl: translate ENOSYS") already fixed this
issue for the first case, but missed the second case.  This patch fixes the
second case.
Reported-by: default avatarJonathan Katz <jkatz@eitmlabs.org>
Closes: https://lore.kernel.org/all/CALKgVmcC1VUV_gJVq70n--omMJZUb4HSh_FqvLTHgNBc+HCLFQ@mail.gmail.com/
Fixes: 02c0cab8 ("fuse: ioctl: translate ENOSYS")
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent a9d1c4c6
......@@ -9,14 +9,23 @@
#include <linux/compat.h>
#include <linux/fileattr.h>
static ssize_t fuse_send_ioctl(struct fuse_mount *fm, struct fuse_args *args)
static ssize_t fuse_send_ioctl(struct fuse_mount *fm, struct fuse_args *args,
struct fuse_ioctl_out *outarg)
{
ssize_t ret = fuse_simple_request(fm, args);
ssize_t ret;
args->out_args[0].size = sizeof(*outarg);
args->out_args[0].value = outarg;
ret = fuse_simple_request(fm, args);
/* Translate ENOSYS, which shouldn't be returned from fs */
if (ret == -ENOSYS)
ret = -ENOTTY;
if (ret >= 0 && outarg->result == -ENOSYS)
outarg->result = -ENOTTY;
return ret;
}
......@@ -264,13 +273,11 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
}
ap.args.out_numargs = 2;
ap.args.out_args[0].size = sizeof(outarg);
ap.args.out_args[0].value = &outarg;
ap.args.out_args[1].size = out_size;
ap.args.out_pages = true;
ap.args.out_argvar = true;
transferred = fuse_send_ioctl(fm, &ap.args);
transferred = fuse_send_ioctl(fm, &ap.args, &outarg);
err = transferred;
if (transferred < 0)
goto out;
......@@ -399,12 +406,10 @@ static int fuse_priv_ioctl(struct inode *inode, struct fuse_file *ff,
args.in_args[1].size = inarg.in_size;
args.in_args[1].value = ptr;
args.out_numargs = 2;
args.out_args[0].size = sizeof(outarg);
args.out_args[0].value = &outarg;
args.out_args[1].size = inarg.out_size;
args.out_args[1].value = ptr;
err = fuse_send_ioctl(fm, &args);
err = fuse_send_ioctl(fm, &args, &outarg);
if (!err) {
if (outarg.result < 0)
err = outarg.result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment