0001
0002
0003
0004
0005
0006 #include "fuse_i.h"
0007
0008 #include <linux/uio.h>
0009 #include <linux/compat.h>
0010 #include <linux/fileattr.h>
0011
0012 static ssize_t fuse_send_ioctl(struct fuse_mount *fm, struct fuse_args *args)
0013 {
0014 ssize_t ret = fuse_simple_request(fm, args);
0015
0016
0017 if (ret == -ENOSYS)
0018 ret = -ENOTTY;
0019
0020 return ret;
0021 }
0022
0023
0024
0025
0026
0027
0028
0029 static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src,
0030 size_t transferred, unsigned count,
0031 bool is_compat)
0032 {
0033 #ifdef CONFIG_COMPAT
0034 if (count * sizeof(struct compat_iovec) == transferred) {
0035 struct compat_iovec *ciov = src;
0036 unsigned i;
0037
0038
0039
0040
0041
0042
0043 if (!is_compat)
0044 return -EINVAL;
0045
0046 for (i = 0; i < count; i++) {
0047 dst[i].iov_base = compat_ptr(ciov[i].iov_base);
0048 dst[i].iov_len = ciov[i].iov_len;
0049 }
0050 return 0;
0051 }
0052 #endif
0053
0054 if (count * sizeof(struct iovec) != transferred)
0055 return -EIO;
0056
0057 memcpy(dst, src, transferred);
0058 return 0;
0059 }
0060
0061
0062 static int fuse_verify_ioctl_iov(struct fuse_conn *fc, struct iovec *iov,
0063 size_t count)
0064 {
0065 size_t n;
0066 u32 max = fc->max_pages << PAGE_SHIFT;
0067
0068 for (n = 0; n < count; n++, iov++) {
0069 if (iov->iov_len > (size_t) max)
0070 return -ENOMEM;
0071 max -= iov->iov_len;
0072 }
0073 return 0;
0074 }
0075
0076 static int fuse_copy_ioctl_iovec(struct fuse_conn *fc, struct iovec *dst,
0077 void *src, size_t transferred, unsigned count,
0078 bool is_compat)
0079 {
0080 unsigned i;
0081 struct fuse_ioctl_iovec *fiov = src;
0082
0083 if (fc->minor < 16) {
0084 return fuse_copy_ioctl_iovec_old(dst, src, transferred,
0085 count, is_compat);
0086 }
0087
0088 if (count * sizeof(struct fuse_ioctl_iovec) != transferred)
0089 return -EIO;
0090
0091 for (i = 0; i < count; i++) {
0092
0093 if (fiov[i].base != (unsigned long) fiov[i].base ||
0094 fiov[i].len != (unsigned long) fiov[i].len)
0095 return -EIO;
0096
0097 dst[i].iov_base = (void __user *) (unsigned long) fiov[i].base;
0098 dst[i].iov_len = (size_t) fiov[i].len;
0099
0100 #ifdef CONFIG_COMPAT
0101 if (is_compat &&
0102 (ptr_to_compat(dst[i].iov_base) != fiov[i].base ||
0103 (compat_size_t) dst[i].iov_len != fiov[i].len))
0104 return -EIO;
0105 #endif
0106 }
0107
0108 return 0;
0109 }
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
0159 unsigned int flags)
0160 {
0161 struct fuse_file *ff = file->private_data;
0162 struct fuse_mount *fm = ff->fm;
0163 struct fuse_ioctl_in inarg = {
0164 .fh = ff->fh,
0165 .cmd = cmd,
0166 .arg = arg,
0167 .flags = flags
0168 };
0169 struct fuse_ioctl_out outarg;
0170 struct iovec *iov_page = NULL;
0171 struct iovec *in_iov = NULL, *out_iov = NULL;
0172 unsigned int in_iovs = 0, out_iovs = 0, max_pages;
0173 size_t in_size, out_size, c;
0174 ssize_t transferred;
0175 int err, i;
0176 struct iov_iter ii;
0177 struct fuse_args_pages ap = {};
0178
0179 #if BITS_PER_LONG == 32
0180 inarg.flags |= FUSE_IOCTL_32BIT;
0181 #else
0182 if (flags & FUSE_IOCTL_COMPAT) {
0183 inarg.flags |= FUSE_IOCTL_32BIT;
0184 #ifdef CONFIG_X86_X32_ABI
0185 if (in_x32_syscall())
0186 inarg.flags |= FUSE_IOCTL_COMPAT_X32;
0187 #endif
0188 }
0189 #endif
0190
0191
0192 BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE);
0193
0194 err = -ENOMEM;
0195 ap.pages = fuse_pages_alloc(fm->fc->max_pages, GFP_KERNEL, &ap.descs);
0196 iov_page = (struct iovec *) __get_free_page(GFP_KERNEL);
0197 if (!ap.pages || !iov_page)
0198 goto out;
0199
0200 fuse_page_descs_length_init(ap.descs, 0, fm->fc->max_pages);
0201
0202
0203
0204
0205
0206 if (!(flags & FUSE_IOCTL_UNRESTRICTED)) {
0207 struct iovec *iov = iov_page;
0208
0209 iov->iov_base = (void __user *)arg;
0210 iov->iov_len = _IOC_SIZE(cmd);
0211
0212 if (_IOC_DIR(cmd) & _IOC_WRITE) {
0213 in_iov = iov;
0214 in_iovs = 1;
0215 }
0216
0217 if (_IOC_DIR(cmd) & _IOC_READ) {
0218 out_iov = iov;
0219 out_iovs = 1;
0220 }
0221 }
0222
0223 retry:
0224 inarg.in_size = in_size = iov_length(in_iov, in_iovs);
0225 inarg.out_size = out_size = iov_length(out_iov, out_iovs);
0226
0227
0228
0229
0230
0231 out_size = max_t(size_t, out_size, PAGE_SIZE);
0232 max_pages = DIV_ROUND_UP(max(in_size, out_size), PAGE_SIZE);
0233
0234
0235 err = -ENOMEM;
0236 if (max_pages > fm->fc->max_pages)
0237 goto out;
0238 while (ap.num_pages < max_pages) {
0239 ap.pages[ap.num_pages] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
0240 if (!ap.pages[ap.num_pages])
0241 goto out;
0242 ap.num_pages++;
0243 }
0244
0245
0246
0247 ap.args.opcode = FUSE_IOCTL;
0248 ap.args.nodeid = ff->nodeid;
0249 ap.args.in_numargs = 1;
0250 ap.args.in_args[0].size = sizeof(inarg);
0251 ap.args.in_args[0].value = &inarg;
0252 if (in_size) {
0253 ap.args.in_numargs++;
0254 ap.args.in_args[1].size = in_size;
0255 ap.args.in_pages = true;
0256
0257 err = -EFAULT;
0258 iov_iter_init(&ii, WRITE, in_iov, in_iovs, in_size);
0259 for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= ap.num_pages); i++) {
0260 c = copy_page_from_iter(ap.pages[i], 0, PAGE_SIZE, &ii);
0261 if (c != PAGE_SIZE && iov_iter_count(&ii))
0262 goto out;
0263 }
0264 }
0265
0266 ap.args.out_numargs = 2;
0267 ap.args.out_args[0].size = sizeof(outarg);
0268 ap.args.out_args[0].value = &outarg;
0269 ap.args.out_args[1].size = out_size;
0270 ap.args.out_pages = true;
0271 ap.args.out_argvar = true;
0272
0273 transferred = fuse_send_ioctl(fm, &ap.args);
0274 err = transferred;
0275 if (transferred < 0)
0276 goto out;
0277
0278
0279 if (outarg.flags & FUSE_IOCTL_RETRY) {
0280 void *vaddr;
0281
0282
0283 err = -EIO;
0284 if (!(flags & FUSE_IOCTL_UNRESTRICTED))
0285 goto out;
0286
0287 in_iovs = outarg.in_iovs;
0288 out_iovs = outarg.out_iovs;
0289
0290
0291
0292
0293
0294 err = -ENOMEM;
0295 if (in_iovs > FUSE_IOCTL_MAX_IOV ||
0296 out_iovs > FUSE_IOCTL_MAX_IOV ||
0297 in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
0298 goto out;
0299
0300 vaddr = kmap_local_page(ap.pages[0]);
0301 err = fuse_copy_ioctl_iovec(fm->fc, iov_page, vaddr,
0302 transferred, in_iovs + out_iovs,
0303 (flags & FUSE_IOCTL_COMPAT) != 0);
0304 kunmap_local(vaddr);
0305 if (err)
0306 goto out;
0307
0308 in_iov = iov_page;
0309 out_iov = in_iov + in_iovs;
0310
0311 err = fuse_verify_ioctl_iov(fm->fc, in_iov, in_iovs);
0312 if (err)
0313 goto out;
0314
0315 err = fuse_verify_ioctl_iov(fm->fc, out_iov, out_iovs);
0316 if (err)
0317 goto out;
0318
0319 goto retry;
0320 }
0321
0322 err = -EIO;
0323 if (transferred > inarg.out_size)
0324 goto out;
0325
0326 err = -EFAULT;
0327 iov_iter_init(&ii, READ, out_iov, out_iovs, transferred);
0328 for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= ap.num_pages); i++) {
0329 c = copy_page_to_iter(ap.pages[i], 0, PAGE_SIZE, &ii);
0330 if (c != PAGE_SIZE && iov_iter_count(&ii))
0331 goto out;
0332 }
0333 err = 0;
0334 out:
0335 free_page((unsigned long) iov_page);
0336 while (ap.num_pages)
0337 __free_page(ap.pages[--ap.num_pages]);
0338 kfree(ap.pages);
0339
0340 return err ? err : outarg.result;
0341 }
0342 EXPORT_SYMBOL_GPL(fuse_do_ioctl);
0343
0344 long fuse_ioctl_common(struct file *file, unsigned int cmd,
0345 unsigned long arg, unsigned int flags)
0346 {
0347 struct inode *inode = file_inode(file);
0348 struct fuse_conn *fc = get_fuse_conn(inode);
0349
0350 if (!fuse_allow_current_process(fc))
0351 return -EACCES;
0352
0353 if (fuse_is_bad(inode))
0354 return -EIO;
0355
0356 return fuse_do_ioctl(file, cmd, arg, flags);
0357 }
0358
0359 long fuse_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0360 {
0361 return fuse_ioctl_common(file, cmd, arg, 0);
0362 }
0363
0364 long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
0365 unsigned long arg)
0366 {
0367 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_COMPAT);
0368 }
0369
0370 static int fuse_priv_ioctl(struct inode *inode, struct fuse_file *ff,
0371 unsigned int cmd, void *ptr, size_t size)
0372 {
0373 struct fuse_mount *fm = ff->fm;
0374 struct fuse_ioctl_in inarg;
0375 struct fuse_ioctl_out outarg;
0376 FUSE_ARGS(args);
0377 int err;
0378
0379 memset(&inarg, 0, sizeof(inarg));
0380 inarg.fh = ff->fh;
0381 inarg.cmd = cmd;
0382
0383 #if BITS_PER_LONG == 32
0384 inarg.flags |= FUSE_IOCTL_32BIT;
0385 #endif
0386 if (S_ISDIR(inode->i_mode))
0387 inarg.flags |= FUSE_IOCTL_DIR;
0388
0389 if (_IOC_DIR(cmd) & _IOC_READ)
0390 inarg.out_size = size;
0391 if (_IOC_DIR(cmd) & _IOC_WRITE)
0392 inarg.in_size = size;
0393
0394 args.opcode = FUSE_IOCTL;
0395 args.nodeid = ff->nodeid;
0396 args.in_numargs = 2;
0397 args.in_args[0].size = sizeof(inarg);
0398 args.in_args[0].value = &inarg;
0399 args.in_args[1].size = inarg.in_size;
0400 args.in_args[1].value = ptr;
0401 args.out_numargs = 2;
0402 args.out_args[0].size = sizeof(outarg);
0403 args.out_args[0].value = &outarg;
0404 args.out_args[1].size = inarg.out_size;
0405 args.out_args[1].value = ptr;
0406
0407 err = fuse_send_ioctl(fm, &args);
0408 if (!err) {
0409 if (outarg.result < 0)
0410 err = outarg.result;
0411 else if (outarg.flags & FUSE_IOCTL_RETRY)
0412 err = -EIO;
0413 }
0414 return err;
0415 }
0416
0417 static struct fuse_file *fuse_priv_ioctl_prepare(struct inode *inode)
0418 {
0419 struct fuse_mount *fm = get_fuse_mount(inode);
0420 bool isdir = S_ISDIR(inode->i_mode);
0421
0422 if (!S_ISREG(inode->i_mode) && !isdir)
0423 return ERR_PTR(-ENOTTY);
0424
0425 return fuse_file_open(fm, get_node_id(inode), O_RDONLY, isdir);
0426 }
0427
0428 static void fuse_priv_ioctl_cleanup(struct inode *inode, struct fuse_file *ff)
0429 {
0430 fuse_file_release(inode, ff, O_RDONLY, NULL, S_ISDIR(inode->i_mode));
0431 }
0432
0433 int fuse_fileattr_get(struct dentry *dentry, struct fileattr *fa)
0434 {
0435 struct inode *inode = d_inode(dentry);
0436 struct fuse_file *ff;
0437 unsigned int flags;
0438 struct fsxattr xfa;
0439 int err;
0440
0441 ff = fuse_priv_ioctl_prepare(inode);
0442 if (IS_ERR(ff))
0443 return PTR_ERR(ff);
0444
0445 if (fa->flags_valid) {
0446 err = fuse_priv_ioctl(inode, ff, FS_IOC_GETFLAGS,
0447 &flags, sizeof(flags));
0448 if (err)
0449 goto cleanup;
0450
0451 fileattr_fill_flags(fa, flags);
0452 } else {
0453 err = fuse_priv_ioctl(inode, ff, FS_IOC_FSGETXATTR,
0454 &xfa, sizeof(xfa));
0455 if (err)
0456 goto cleanup;
0457
0458 fileattr_fill_xflags(fa, xfa.fsx_xflags);
0459 fa->fsx_extsize = xfa.fsx_extsize;
0460 fa->fsx_nextents = xfa.fsx_nextents;
0461 fa->fsx_projid = xfa.fsx_projid;
0462 fa->fsx_cowextsize = xfa.fsx_cowextsize;
0463 }
0464 cleanup:
0465 fuse_priv_ioctl_cleanup(inode, ff);
0466
0467 return err;
0468 }
0469
0470 int fuse_fileattr_set(struct user_namespace *mnt_userns,
0471 struct dentry *dentry, struct fileattr *fa)
0472 {
0473 struct inode *inode = d_inode(dentry);
0474 struct fuse_file *ff;
0475 unsigned int flags = fa->flags;
0476 struct fsxattr xfa;
0477 int err;
0478
0479 ff = fuse_priv_ioctl_prepare(inode);
0480 if (IS_ERR(ff))
0481 return PTR_ERR(ff);
0482
0483 if (fa->flags_valid) {
0484 err = fuse_priv_ioctl(inode, ff, FS_IOC_SETFLAGS,
0485 &flags, sizeof(flags));
0486 if (err)
0487 goto cleanup;
0488 } else {
0489 memset(&xfa, 0, sizeof(xfa));
0490 xfa.fsx_xflags = fa->fsx_xflags;
0491 xfa.fsx_extsize = fa->fsx_extsize;
0492 xfa.fsx_nextents = fa->fsx_nextents;
0493 xfa.fsx_projid = fa->fsx_projid;
0494 xfa.fsx_cowextsize = fa->fsx_cowextsize;
0495
0496 err = fuse_priv_ioctl(inode, ff, FS_IOC_FSSETXATTR,
0497 &xfa, sizeof(xfa));
0498 }
0499
0500 cleanup:
0501 fuse_priv_ioctl_cleanup(inode, ff);
0502
0503 return err;
0504 }