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