File Index
Files and directories
Sign in
FILE

ioctl.c

File preview with syntax highlighting.

linux-6.19.14/fs/ioctl.c C
  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 */
 44static 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
 58static 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 */
111int 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}
152EXPORT_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 */
167int 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}
197EXPORT_SYMBOL(fiemap_prep);
198
199static 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
230static 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
250static 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 */
268static 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 */
296static 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
322static 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
340static 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
363static 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
385static 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
402static 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
415static 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
450out:
451	kfree(same);
452	return ret;
453}
454
455static 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
468static 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 */
492static 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
583SYSCALL_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 */
629long 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}
636EXPORT_SYMBOL(compat_ptr_ioctl);
637
638COMPAT_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
~/ Read-only file preview.