ioctl.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/fs/ioctl.c
  4. *
  5. * Copyright (C) 1991, 1992 Linus Torvalds
  6. */
  7. #include <linux/syscalls.h>
  8. #include <linux/mm.h>
  9. #include <linux/capability.h>
  10. #include <linux/compat.h>
  11. #include <linux/file.h>
  12. #include <linux/fs.h>
  13. #include <linux/security.h>
  14. #include <linux/export.h>
  15. #include <linux/uaccess.h>
  16. #include <linux/writeback.h>
  17. #include <linux/buffer_head.h>
  18. #include <linux/falloc.h>
  19. #include <linux/sched/signal.h>
  20. #include <linux/fiemap.h>
  21. #include <linux/mount.h>
  22. #include <linux/fscrypt.h>
  23. #include <linux/fileattr.h>
  24. #include "internal.h"
  25. #include <asm/ioctls.h>
  26. /* So that the fiemap access checks can't overflow on 32 bit machines. */
  27. #define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
  28. /**
  29. * vfs_ioctl - call filesystem specific ioctl methods
  30. * @filp: open file to invoke ioctl method on
  31. * @cmd: ioctl command to execute
  32. * @arg: command-specific argument for ioctl
  33. *
  34. * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
  35. * returns -ENOTTY.
  36. *
  37. * Returns 0 on success, -errno on error.
  38. */
  39. static int vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  40. {
  41. int error = -ENOTTY;
  42. if (!filp->f_op->unlocked_ioctl)
  43. goto out;
  44. error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
  45. if (error == -ENOIOCTLCMD)
  46. error = -ENOTTY;
  47. out:
  48. return error;
  49. }
  50. static int ioctl_fibmap(struct file *filp, int __user *p)
  51. {
  52. struct inode *inode = file_inode(filp);
  53. struct super_block *sb = inode->i_sb;
  54. int error, ur_block;
  55. sector_t block;
  56. if (!capable(CAP_SYS_RAWIO))
  57. return -EPERM;
  58. error = get_user(ur_block, p);
  59. if (error)
  60. return error;
  61. if (ur_block < 0)
  62. return -EINVAL;
  63. block = ur_block;
  64. error = bmap(inode, &block);
  65. if (block > INT_MAX) {
  66. error = -ERANGE;
  67. pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n",
  68. current->comm, task_pid_nr(current),
  69. sb->s_id, filp);
  70. }
  71. if (error)
  72. ur_block = 0;
  73. else
  74. ur_block = block;
  75. if (put_user(ur_block, p))
  76. error = -EFAULT;
  77. return error;
  78. }
  79. /**
  80. * fiemap_fill_next_extent - Fiemap helper function
  81. * @fieinfo: Fiemap context passed into ->fiemap
  82. * @logical: Extent logical start offset, in bytes
  83. * @phys: Extent physical start offset, in bytes
  84. * @len: Extent length, in bytes
  85. * @flags: FIEMAP_EXTENT flags that describe this extent
  86. *
  87. * Called from file system ->fiemap callback. Will populate extent
  88. * info as passed in via arguments and copy to user memory. On
  89. * success, extent count on fieinfo is incremented.
  90. *
  91. * Returns 0 on success, -errno on error, 1 if this was the last
  92. * extent that will fit in user array.
  93. */
  94. int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
  95. u64 phys, u64 len, u32 flags)
  96. {
  97. struct fiemap_extent extent;
  98. struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
  99. /* only count the extents */
  100. if (fieinfo->fi_extents_max == 0) {
  101. fieinfo->fi_extents_mapped++;
  102. return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
  103. }
  104. if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
  105. return 1;
  106. #define SET_UNKNOWN_FLAGS (FIEMAP_EXTENT_DELALLOC)
  107. #define SET_NO_UNMOUNTED_IO_FLAGS (FIEMAP_EXTENT_DATA_ENCRYPTED)
  108. #define SET_NOT_ALIGNED_FLAGS (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
  109. if (flags & SET_UNKNOWN_FLAGS)
  110. flags |= FIEMAP_EXTENT_UNKNOWN;
  111. if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
  112. flags |= FIEMAP_EXTENT_ENCODED;
  113. if (flags & SET_NOT_ALIGNED_FLAGS)
  114. flags |= FIEMAP_EXTENT_NOT_ALIGNED;
  115. memset(&extent, 0, sizeof(extent));
  116. extent.fe_logical = logical;
  117. extent.fe_physical = phys;
  118. extent.fe_length = len;
  119. extent.fe_flags = flags;
  120. dest += fieinfo->fi_extents_mapped;
  121. if (copy_to_user(dest, &extent, sizeof(extent)))
  122. return -EFAULT;
  123. fieinfo->fi_extents_mapped++;
  124. if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
  125. return 1;
  126. return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
  127. }
  128. EXPORT_SYMBOL(fiemap_fill_next_extent);
  129. /**
  130. * fiemap_prep - check validity of requested flags for fiemap
  131. * @inode: Inode to operate on
  132. * @fieinfo: Fiemap context passed into ->fiemap
  133. * @start: Start of the mapped range
  134. * @len: Length of the mapped range, can be truncated by this function.
  135. * @supported_flags: Set of fiemap flags that the file system understands
  136. *
  137. * This function must be called from each ->fiemap instance to validate the
  138. * fiemap request against the file system parameters.
  139. *
  140. * Returns 0 on success, or a negative error on failure.
  141. */
  142. int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
  143. u64 start, u64 *len, u32 supported_flags)
  144. {
  145. u64 maxbytes = inode->i_sb->s_maxbytes;
  146. u32 incompat_flags;
  147. int ret = 0;
  148. if (*len == 0)
  149. return -EINVAL;
  150. if (start >= maxbytes)
  151. return -EFBIG;
  152. /*
  153. * Shrink request scope to what the fs can actually handle.
  154. */
  155. if (*len > maxbytes || (maxbytes - *len) < start)
  156. *len = maxbytes - start;
  157. supported_flags |= FIEMAP_FLAG_SYNC;
  158. supported_flags &= FIEMAP_FLAGS_COMPAT;
  159. incompat_flags = fieinfo->fi_flags & ~supported_flags;
  160. if (incompat_flags) {
  161. fieinfo->fi_flags = incompat_flags;
  162. return -EBADR;
  163. }
  164. if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
  165. ret = filemap_write_and_wait(inode->i_mapping);
  166. return ret;
  167. }
  168. EXPORT_SYMBOL(fiemap_prep);
  169. static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap)
  170. {
  171. struct fiemap fiemap;
  172. struct fiemap_extent_info fieinfo = { 0, };
  173. struct inode *inode = file_inode(filp);
  174. int error;
  175. if (!inode->i_op->fiemap)
  176. return -EOPNOTSUPP;
  177. if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
  178. return -EFAULT;
  179. if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
  180. return -EINVAL;
  181. fieinfo.fi_flags = fiemap.fm_flags;
  182. fieinfo.fi_extents_max = fiemap.fm_extent_count;
  183. fieinfo.fi_extents_start = ufiemap->fm_extents;
  184. error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start,
  185. fiemap.fm_length);
  186. fiemap.fm_flags = fieinfo.fi_flags;
  187. fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
  188. if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
  189. error = -EFAULT;
  190. return error;
  191. }
  192. static int ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
  193. u64 off, u64 olen, u64 destoff)
  194. {
  195. CLASS(fd, src_file)(srcfd);
  196. loff_t cloned;
  197. int ret;
  198. if (fd_empty(src_file))
  199. return -EBADF;
  200. cloned = vfs_clone_file_range(fd_file(src_file), off, dst_file, destoff,
  201. olen, 0);
  202. if (cloned < 0)
  203. ret = cloned;
  204. else if (olen && cloned != olen)
  205. ret = -EINVAL;
  206. else
  207. ret = 0;
  208. return ret;
  209. }
  210. static int ioctl_file_clone_range(struct file *file,
  211. struct file_clone_range __user *argp)
  212. {
  213. struct file_clone_range args;
  214. if (copy_from_user(&args, argp, sizeof(args)))
  215. return -EFAULT;
  216. return ioctl_file_clone(file, args.src_fd, args.src_offset,
  217. args.src_length, args.dest_offset);
  218. }
  219. /*
  220. * This provides compatibility with legacy XFS pre-allocation ioctls
  221. * which predate the fallocate syscall.
  222. *
  223. * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
  224. * are used here, rest are ignored.
  225. */
  226. static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
  227. {
  228. struct inode *inode = file_inode(filp);
  229. struct space_resv sr;
  230. if (copy_from_user(&sr, argp, sizeof(sr)))
  231. return -EFAULT;
  232. switch (sr.l_whence) {
  233. case SEEK_SET:
  234. break;
  235. case SEEK_CUR:
  236. sr.l_start += filp->f_pos;
  237. break;
  238. case SEEK_END:
  239. sr.l_start += i_size_read(inode);
  240. break;
  241. default:
  242. return -EINVAL;
  243. }
  244. return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
  245. sr.l_len);
  246. }
  247. /* on ia32 l_start is on a 32-bit boundary */
  248. #if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
  249. /* just account for different alignment */
  250. static int compat_ioctl_preallocate(struct file *file, int mode,
  251. struct space_resv_32 __user *argp)
  252. {
  253. struct inode *inode = file_inode(file);
  254. struct space_resv_32 sr;
  255. if (copy_from_user(&sr, argp, sizeof(sr)))
  256. return -EFAULT;
  257. switch (sr.l_whence) {
  258. case SEEK_SET:
  259. break;
  260. case SEEK_CUR:
  261. sr.l_start += file->f_pos;
  262. break;
  263. case SEEK_END:
  264. sr.l_start += i_size_read(inode);
  265. break;
  266. default:
  267. return -EINVAL;
  268. }
  269. return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
  270. }
  271. #endif
  272. static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
  273. {
  274. switch (cmd) {
  275. case FIBMAP:
  276. return ioctl_fibmap(filp, p);
  277. case FS_IOC_RESVSP:
  278. case FS_IOC_RESVSP64:
  279. return ioctl_preallocate(filp, 0, p);
  280. case FS_IOC_UNRESVSP:
  281. case FS_IOC_UNRESVSP64:
  282. return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
  283. case FS_IOC_ZERO_RANGE:
  284. return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
  285. }
  286. return -ENOIOCTLCMD;
  287. }
  288. static int ioctl_fionbio(struct file *filp, int __user *argp)
  289. {
  290. unsigned int flag;
  291. int on, error;
  292. error = get_user(on, argp);
  293. if (error)
  294. return error;
  295. flag = O_NONBLOCK;
  296. #ifdef __sparc__
  297. /* SunOS compatibility item. */
  298. if (O_NONBLOCK != O_NDELAY)
  299. flag |= O_NDELAY;
  300. #endif
  301. spin_lock(&filp->f_lock);
  302. if (on)
  303. filp->f_flags |= flag;
  304. else
  305. filp->f_flags &= ~flag;
  306. spin_unlock(&filp->f_lock);
  307. return error;
  308. }
  309. static int ioctl_fioasync(unsigned int fd, struct file *filp,
  310. int __user *argp)
  311. {
  312. unsigned int flag;
  313. int on, error;
  314. error = get_user(on, argp);
  315. if (error)
  316. return error;
  317. flag = on ? FASYNC : 0;
  318. /* Did FASYNC state change ? */
  319. if ((flag ^ filp->f_flags) & FASYNC) {
  320. if (filp->f_op->fasync)
  321. /* fasync() adjusts filp->f_flags */
  322. error = filp->f_op->fasync(fd, filp, on);
  323. else
  324. error = -ENOTTY;
  325. }
  326. return error < 0 ? error : 0;
  327. }
  328. static int ioctl_fsfreeze(struct file *filp)
  329. {
  330. struct super_block *sb = file_inode(filp)->i_sb;
  331. if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
  332. return -EPERM;
  333. /* If filesystem doesn't support freeze feature, return. */
  334. if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL)
  335. return -EOPNOTSUPP;
  336. /* Freeze */
  337. if (sb->s_op->freeze_super)
  338. return sb->s_op->freeze_super(sb, FREEZE_HOLDER_USERSPACE, NULL);
  339. return freeze_super(sb, FREEZE_HOLDER_USERSPACE, NULL);
  340. }
  341. static int ioctl_fsthaw(struct file *filp)
  342. {
  343. struct super_block *sb = file_inode(filp)->i_sb;
  344. if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
  345. return -EPERM;
  346. /* Thaw */
  347. if (sb->s_op->thaw_super)
  348. return sb->s_op->thaw_super(sb, FREEZE_HOLDER_USERSPACE, NULL);
  349. return thaw_super(sb, FREEZE_HOLDER_USERSPACE, NULL);
  350. }
  351. static int ioctl_file_dedupe_range(struct file *file,
  352. struct file_dedupe_range __user *argp)
  353. {
  354. struct file_dedupe_range *same = NULL;
  355. int ret;
  356. unsigned long size;
  357. u16 count;
  358. if (get_user(count, &argp->dest_count)) {
  359. ret = -EFAULT;
  360. goto out;
  361. }
  362. size = struct_size(same, info, count);
  363. if (size > PAGE_SIZE) {
  364. ret = -ENOMEM;
  365. goto out;
  366. }
  367. same = memdup_user(argp, size);
  368. if (IS_ERR(same)) {
  369. ret = PTR_ERR(same);
  370. same = NULL;
  371. goto out;
  372. }
  373. same->dest_count = count;
  374. ret = vfs_dedupe_file_range(file, same);
  375. if (ret)
  376. goto out;
  377. ret = copy_to_user(argp, same, size);
  378. if (ret)
  379. ret = -EFAULT;
  380. out:
  381. kfree(same);
  382. return ret;
  383. }
  384. static int ioctl_getfsuuid(struct file *file, void __user *argp)
  385. {
  386. struct super_block *sb = file_inode(file)->i_sb;
  387. struct fsuuid2 u = { .len = sb->s_uuid_len, };
  388. if (!sb->s_uuid_len)
  389. return -ENOTTY;
  390. memcpy(&u.uuid[0], &sb->s_uuid, sb->s_uuid_len);
  391. return copy_to_user(argp, &u, sizeof(u)) ? -EFAULT : 0;
  392. }
  393. static int ioctl_get_fs_sysfs_path(struct file *file, void __user *argp)
  394. {
  395. struct super_block *sb = file_inode(file)->i_sb;
  396. if (!strlen(sb->s_sysfs_name))
  397. return -ENOTTY;
  398. struct fs_sysfs_path u = {};
  399. u.len = scnprintf(u.name, sizeof(u.name), "%s/%s", sb->s_type->name, sb->s_sysfs_name);
  400. return copy_to_user(argp, &u, sizeof(u)) ? -EFAULT : 0;
  401. }
  402. /*
  403. * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
  404. * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
  405. *
  406. * When you add any new common ioctls to the switches above and below,
  407. * please ensure they have compatible arguments in compat mode.
  408. *
  409. * The LSM mailing list should also be notified of any command additions or
  410. * changes, as specific LSMs may be affected.
  411. */
  412. static int do_vfs_ioctl(struct file *filp, unsigned int fd,
  413. unsigned int cmd, unsigned long arg)
  414. {
  415. void __user *argp = (void __user *)arg;
  416. struct inode *inode = file_inode(filp);
  417. switch (cmd) {
  418. case FIOCLEX:
  419. set_close_on_exec(fd, 1);
  420. return 0;
  421. case FIONCLEX:
  422. set_close_on_exec(fd, 0);
  423. return 0;
  424. case FIONBIO:
  425. return ioctl_fionbio(filp, argp);
  426. case FIOASYNC:
  427. return ioctl_fioasync(fd, filp, argp);
  428. case FIOQSIZE:
  429. if (S_ISDIR(inode->i_mode) ||
  430. (S_ISREG(inode->i_mode) && !IS_ANON_FILE(inode)) ||
  431. S_ISLNK(inode->i_mode)) {
  432. loff_t res = inode_get_bytes(inode);
  433. return copy_to_user(argp, &res, sizeof(res)) ?
  434. -EFAULT : 0;
  435. }
  436. return -ENOTTY;
  437. case FIFREEZE:
  438. return ioctl_fsfreeze(filp);
  439. case FITHAW:
  440. return ioctl_fsthaw(filp);
  441. case FS_IOC_FIEMAP:
  442. return ioctl_fiemap(filp, argp);
  443. case FIGETBSZ:
  444. /* anon_bdev filesystems may not have a block size */
  445. if (!inode->i_sb->s_blocksize)
  446. return -EINVAL;
  447. return put_user(inode->i_sb->s_blocksize, (int __user *)argp);
  448. case FICLONE:
  449. return ioctl_file_clone(filp, arg, 0, 0, 0);
  450. case FICLONERANGE:
  451. return ioctl_file_clone_range(filp, argp);
  452. case FIDEDUPERANGE:
  453. return ioctl_file_dedupe_range(filp, argp);
  454. case FIONREAD:
  455. if (!S_ISREG(inode->i_mode) || IS_ANON_FILE(inode))
  456. return vfs_ioctl(filp, cmd, arg);
  457. return put_user(i_size_read(inode) - filp->f_pos,
  458. (int __user *)argp);
  459. case FS_IOC_GETFLAGS:
  460. return ioctl_getflags(filp, argp);
  461. case FS_IOC_SETFLAGS:
  462. return ioctl_setflags(filp, argp);
  463. case FS_IOC_FSGETXATTR:
  464. return ioctl_fsgetxattr(filp, argp);
  465. case FS_IOC_FSSETXATTR:
  466. return ioctl_fssetxattr(filp, argp);
  467. case FS_IOC_GETFSUUID:
  468. return ioctl_getfsuuid(filp, argp);
  469. case FS_IOC_GETFSSYSFSPATH:
  470. return ioctl_get_fs_sysfs_path(filp, argp);
  471. default:
  472. if (S_ISREG(inode->i_mode) && !IS_ANON_FILE(inode))
  473. return file_ioctl(filp, cmd, argp);
  474. break;
  475. }
  476. return -ENOIOCTLCMD;
  477. }
  478. SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
  479. {
  480. CLASS(fd, f)(fd);
  481. int error;
  482. if (fd_empty(f))
  483. return -EBADF;
  484. error = security_file_ioctl(fd_file(f), cmd, arg);
  485. if (error)
  486. return error;
  487. error = do_vfs_ioctl(fd_file(f), fd, cmd, arg);
  488. if (error == -ENOIOCTLCMD)
  489. error = vfs_ioctl(fd_file(f), cmd, arg);
  490. return error;
  491. }
  492. #ifdef CONFIG_COMPAT
  493. /**
  494. * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation
  495. * @file: The file to operate on.
  496. * @cmd: The ioctl command number.
  497. * @arg: The argument to the ioctl.
  498. *
  499. * This is not normally called as a function, but instead set in struct
  500. * file_operations as
  501. *
  502. * .compat_ioctl = compat_ptr_ioctl,
  503. *
  504. * On most architectures, the compat_ptr_ioctl() just passes all arguments
  505. * to the corresponding ->ioctl handler. The exception is arch/s390, where
  506. * compat_ptr() clears the top bit of a 32-bit pointer value, so user space
  507. * pointers to the second 2GB alias the first 2GB, as is the case for
  508. * native 32-bit s390 user space.
  509. *
  510. * The compat_ptr_ioctl() function must therefore be used only with ioctl
  511. * functions that either ignore the argument or pass a pointer to a
  512. * compatible data type.
  513. *
  514. * If any ioctl command handled by fops->unlocked_ioctl passes a plain
  515. * integer instead of a pointer, or any of the passed data types
  516. * is incompatible between 32-bit and 64-bit architectures, a proper
  517. * handler is required instead of compat_ptr_ioctl.
  518. */
  519. long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  520. {
  521. if (!file->f_op->unlocked_ioctl)
  522. return -ENOIOCTLCMD;
  523. return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
  524. }
  525. EXPORT_SYMBOL(compat_ptr_ioctl);
  526. COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
  527. compat_ulong_t, arg)
  528. {
  529. CLASS(fd, f)(fd);
  530. int error;
  531. if (fd_empty(f))
  532. return -EBADF;
  533. error = security_file_ioctl_compat(fd_file(f), cmd, arg);
  534. if (error)
  535. return error;
  536. switch (cmd) {
  537. /* FICLONE takes an int argument, so don't use compat_ptr() */
  538. case FICLONE:
  539. error = ioctl_file_clone(fd_file(f), arg, 0, 0, 0);
  540. break;
  541. #if defined(CONFIG_X86_64)
  542. /* these get messy on amd64 due to alignment differences */
  543. case FS_IOC_RESVSP_32:
  544. case FS_IOC_RESVSP64_32:
  545. error = compat_ioctl_preallocate(fd_file(f), 0, compat_ptr(arg));
  546. break;
  547. case FS_IOC_UNRESVSP_32:
  548. case FS_IOC_UNRESVSP64_32:
  549. error = compat_ioctl_preallocate(fd_file(f), FALLOC_FL_PUNCH_HOLE,
  550. compat_ptr(arg));
  551. break;
  552. case FS_IOC_ZERO_RANGE_32:
  553. error = compat_ioctl_preallocate(fd_file(f), FALLOC_FL_ZERO_RANGE,
  554. compat_ptr(arg));
  555. break;
  556. #endif
  557. /*
  558. * These access 32-bit values anyway so no further handling is
  559. * necessary.
  560. */
  561. case FS_IOC32_GETFLAGS:
  562. case FS_IOC32_SETFLAGS:
  563. cmd = (cmd == FS_IOC32_GETFLAGS) ?
  564. FS_IOC_GETFLAGS : FS_IOC_SETFLAGS;
  565. fallthrough;
  566. /*
  567. * everything else in do_vfs_ioctl() takes either a compatible
  568. * pointer argument or no argument -- call it with a modified
  569. * argument.
  570. */
  571. default:
  572. error = do_vfs_ioctl(fd_file(f), fd, cmd,
  573. (unsigned long)compat_ptr(arg));
  574. if (error != -ENOIOCTLCMD)
  575. break;
  576. if (fd_file(f)->f_op->compat_ioctl)
  577. error = fd_file(f)->f_op->compat_ioctl(fd_file(f), cmd, arg);
  578. if (error == -ENOIOCTLCMD)
  579. error = -ENOTTY;
  580. break;
  581. }
  582. return error;
  583. }
  584. #endif