Skip to content

Commit 6a567e9

Browse files
author
Miklos Szeredi
committed
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 02c0cab ("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: Jonathan Katz <[email protected]> Closes: https://lore.kernel.org/all/CALKgVmcC1VUV_gJVq70n--omMJZUb4HSh_FqvLTHgNBc+HCLFQ@mail.gmail.com/ Fixes: 02c0cab ("fuse: ioctl: translate ENOSYS") Cc: <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent a9d1c4c commit 6a567e9

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

fs/fuse/ioctl.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,23 @@
99
#include <linux/compat.h>
1010
#include <linux/fileattr.h>
1111

12-
static ssize_t fuse_send_ioctl(struct fuse_mount *fm, struct fuse_args *args)
12+
static ssize_t fuse_send_ioctl(struct fuse_mount *fm, struct fuse_args *args,
13+
struct fuse_ioctl_out *outarg)
1314
{
14-
ssize_t ret = fuse_simple_request(fm, args);
15+
ssize_t ret;
16+
17+
args->out_args[0].size = sizeof(*outarg);
18+
args->out_args[0].value = outarg;
19+
20+
ret = fuse_simple_request(fm, args);
1521

1622
/* Translate ENOSYS, which shouldn't be returned from fs */
1723
if (ret == -ENOSYS)
1824
ret = -ENOTTY;
1925

26+
if (ret >= 0 && outarg->result == -ENOSYS)
27+
outarg->result = -ENOTTY;
28+
2029
return ret;
2130
}
2231

@@ -264,13 +273,11 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
264273
}
265274

266275
ap.args.out_numargs = 2;
267-
ap.args.out_args[0].size = sizeof(outarg);
268-
ap.args.out_args[0].value = &outarg;
269276
ap.args.out_args[1].size = out_size;
270277
ap.args.out_pages = true;
271278
ap.args.out_argvar = true;
272279

273-
transferred = fuse_send_ioctl(fm, &ap.args);
280+
transferred = fuse_send_ioctl(fm, &ap.args, &outarg);
274281
err = transferred;
275282
if (transferred < 0)
276283
goto out;
@@ -399,12 +406,10 @@ static int fuse_priv_ioctl(struct inode *inode, struct fuse_file *ff,
399406
args.in_args[1].size = inarg.in_size;
400407
args.in_args[1].value = ptr;
401408
args.out_numargs = 2;
402-
args.out_args[0].size = sizeof(outarg);
403-
args.out_args[0].value = &outarg;
404409
args.out_args[1].size = inarg.out_size;
405410
args.out_args[1].value = ptr;
406411

407-
err = fuse_send_ioctl(fm, &args);
412+
err = fuse_send_ioctl(fm, &args, &outarg);
408413
if (!err) {
409414
if (outarg.result < 0)
410415
err = outarg.result;

0 commit comments

Comments
 (0)