1 // SPDX-License-Identifier: GPL-2.0
3 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
5 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
6 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
7 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
8 * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz)
10 * These routines maintain argument size conversion between 32bit and 64bit
14 #include <linux/types.h>
15 #include <linux/compat.h>
16 #include <linux/kernel.h>
17 #include <linux/capability.h>
18 #include <linux/compiler.h>
19 #include <linux/sched.h>
20 #include <linux/smp.h>
21 #include <linux/ioctl.h>
23 #include <linux/raid/md_u.h>
24 #include <linux/falloc.h>
25 #include <linux/file.h>
26 #include <linux/ppp-ioctl.h>
27 #include <linux/if_pppox.h>
28 #include <linux/tty.h>
29 #include <linux/vt_kern.h>
30 #include <linux/blkdev.h>
31 #include <linux/serial.h>
32 #include <linux/ctype.h>
33 #include <linux/syscalls.h>
34 #include <linux/gfp.h>
35 #include <linux/cec.h>
39 #include <linux/uaccess.h>
40 #include <linux/watchdog.h>
42 #include <linux/hiddev.h>
44 COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
45 compat_ulong_t, arg32)
47 unsigned long arg = arg32;
48 struct fd f = fdget(fd);
53 /* RED-PEN how should LSM module know it's handling 32bit? */
54 error = security_file_ioctl(f.file, cmd, arg);
59 /* these are never seen by ->ioctl(), no argument or int argument */
66 /* these are never seen by ->ioctl(), pointer argument */
76 * The next group is the stuff handled inside file_ioctl().
77 * For regular files these never reach ->ioctl(); for
78 * devices, sockets, etc. they do and one (FIONREAD) is
79 * even accepted in some cases. In all those cases
80 * argument has the same type, so we can handle these
81 * here, shunting them towards do_vfs_ioctl().
82 * ->compat_ioctl() will never see any of those.
84 /* pointer argument, never actually handled by ->ioctl() */
87 /* handled by some ->ioctl(); always a pointer to int */
90 /* these get messy on amd64 due to alignment differences */
91 #if defined(CONFIG_X86_64)
92 case FS_IOC_RESVSP_32:
93 case FS_IOC_RESVSP64_32:
94 error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
96 case FS_IOC_UNRESVSP_32:
97 case FS_IOC_UNRESVSP64_32:
98 error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
101 case FS_IOC_ZERO_RANGE_32:
102 error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
107 case FS_IOC_RESVSP64:
108 case FS_IOC_UNRESVSP:
109 case FS_IOC_UNRESVSP64:
110 case FS_IOC_ZERO_RANGE:
115 if (f.file->f_op->compat_ioctl) {
116 error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
117 if (error != -ENOIOCTLCMD)
126 arg = (unsigned long)compat_ptr(arg);
128 error = do_vfs_ioctl(f.file, fd, cmd, arg);