]> Git Repo - linux.git/blame - fs/compat_ioctl.c
Merge branch 'kcsan.2020.01.07a' into locking/kcsan
[linux.git] / fs / compat_ioctl.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
1da177e4
LT
2/*
3 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
4 *
5 * Copyright (C) 1997-2000 Jakub Jelinek ([email protected])
6 * Copyright (C) 1998 Eddie C. Dost ([email protected])
7 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
a2531293 8 * Copyright (C) 2003 Pavel Machek ([email protected])
1da177e4
LT
9 *
10 * These routines maintain argument size conversion between 32bit and 64bit
11 * ioctls.
12 */
13
1da177e4
LT
14#include <linux/types.h>
15#include <linux/compat.h>
16#include <linux/kernel.h>
16f7e0fe 17#include <linux/capability.h>
1da177e4
LT
18#include <linux/compiler.h>
19#include <linux/sched.h>
20#include <linux/smp.h>
1da177e4
LT
21#include <linux/ioctl.h>
22#include <linux/if.h>
bff61975 23#include <linux/raid/md_u.h>
3e63cbb1 24#include <linux/falloc.h>
1da177e4 25#include <linux/file.h>
4b32da2b 26#include <linux/ppp-ioctl.h>
1da177e4 27#include <linux/if_pppox.h>
1da177e4
LT
28#include <linux/tty.h>
29#include <linux/vt_kern.h>
1da177e4 30#include <linux/blkdev.h>
1da177e4 31#include <linux/serial.h>
1da177e4 32#include <linux/ctype.h>
1da177e4 33#include <linux/syscalls.h>
5a0e3ad6 34#include <linux/gfp.h>
594edf39 35#include <linux/cec.h>
1da177e4 36
66cf191f
AV
37#include "internal.h"
38
3c3622dc 39#ifdef CONFIG_BLOCK
390192b3
JS
40#include <linux/cdrom.h>
41#include <linux/fd.h>
1da177e4 42#include <scsi/scsi.h>
1da177e4 43#include <scsi/scsi_ioctl.h>
1da177e4 44#include <scsi/sg.h>
3c3622dc 45#endif
1da177e4 46
7c0f6ba6 47#include <linux/uaccess.h>
1da177e4 48#include <linux/watchdog.h>
1da177e4 49
1da177e4
LT
50#include <linux/hiddev.h>
51
6e87abd0 52
661f627d
AB
53#include <linux/sort.h>
54
661f627d
AB
55/*
56 * simple reversible transform to make our table more evenly
57 * distributed after sorting.
58 */
59#define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff)
6272e266 60
9280cdd6 61#define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd),
661f627d 62static unsigned int ioctl_pointer[] = {
3c3622dc 63#ifdef CONFIG_BLOCK
644fd4f5
CH
64/* Big S */
65COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
66COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
67COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
68COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
69COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
70COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
71COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
72COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
3c3622dc 73#endif
3c3622dc 74#ifdef CONFIG_BLOCK
644fd4f5 75/* SG stuff */
98aaaec4 76COMPATIBLE_IOCTL(SG_IO)
fd6c3d5a 77COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
644fd4f5
CH
78COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
79COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
80COMPATIBLE_IOCTL(SG_EMULATED_HOST)
644fd4f5
CH
81COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
82COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
83COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
84COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
85COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
86COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
87COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
88COMPATIBLE_IOCTL(SG_GET_PACK_ID)
89COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
90COMPATIBLE_IOCTL(SG_SET_DEBUG)
91COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
92COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
93COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
94COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
95COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
96COMPATIBLE_IOCTL(SG_SCSI_RESET)
97COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
98COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
99COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
3c3622dc 100#endif
e6a6d2ef 101};
6e87abd0 102
5a07ea0b
AB
103/*
104 * Convert common ioctl arguments based on their command number
105 *
106 * Please do not add any code in here. Instead, implement
107 * a compat_ioctl operation in the place that handleѕ the
108 * ioctl for the native case.
109 */
66cf191f 110static long do_ioctl_trans(unsigned int cmd,
5a07ea0b
AB
111 unsigned long arg, struct file *file)
112{
5a07ea0b
AB
113 return -ENOIOCTLCMD;
114}
115
661f627d
AB
116static int compat_ioctl_check_table(unsigned int xcmd)
117{
8f5d9f2c 118#ifdef CONFIG_BLOCK
661f627d
AB
119 int i;
120 const int max = ARRAY_SIZE(ioctl_pointer) - 1;
121
122 BUILD_BUG_ON(max >= (1 << 16));
123
124 /* guess initial offset into table, assuming a
125 normalized distribution */
126 i = ((xcmd >> 16) * max) >> 16;
127
128 /* do linear search up first, until greater or equal */
129 while (ioctl_pointer[i] < xcmd && i < max)
130 i++;
131
132 /* then do linear search down */
133 while (ioctl_pointer[i] > xcmd && i > 0)
134 i--;
135
136 return ioctl_pointer[i] == xcmd;
8f5d9f2c
AB
137#else
138 return 0;
139#endif
661f627d
AB
140}
141
932602e2
HC
142COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
143 compat_ulong_t, arg32)
6272e266 144{
932602e2 145 unsigned long arg = arg32;
2903ff01 146 struct fd f = fdget(fd);
6272e266 147 int error = -EBADF;
2903ff01 148 if (!f.file)
6272e266
CH
149 goto out;
150
151 /* RED-PEN how should LSM module know it's handling 32bit? */
2903ff01 152 error = security_file_ioctl(f.file, cmd, arg);
6272e266
CH
153 if (error)
154 goto out_fput;
155
6272e266 156 switch (cmd) {
37ecf8b2 157 /* these are never seen by ->ioctl(), no argument or int argument */
6272e266
CH
158 case FIOCLEX:
159 case FIONCLEX:
37ecf8b2
AV
160 case FIFREEZE:
161 case FITHAW:
162 case FICLONE:
163 goto do_ioctl;
164 /* these are never seen by ->ioctl(), pointer argument */
6272e266
CH
165 case FIONBIO:
166 case FIOASYNC:
167 case FIOQSIZE:
37ecf8b2
AV
168 case FS_IOC_FIEMAP:
169 case FIGETBSZ:
170 case FICLONERANGE:
171 case FIDEDUPERANGE:
172 goto found_handler;
173 /*
174 * The next group is the stuff handled inside file_ioctl().
175 * For regular files these never reach ->ioctl(); for
176 * devices, sockets, etc. they do and one (FIONREAD) is
177 * even accepted in some cases. In all those cases
178 * argument has the same type, so we can handle these
179 * here, shunting them towards do_vfs_ioctl().
180 * ->compat_ioctl() will never see any of those.
181 */
182 /* pointer argument, never actually handled by ->ioctl() */
183 case FIBMAP:
184 goto found_handler;
185 /* handled by some ->ioctl(); always a pointer to int */
186 case FIONREAD:
187 goto found_handler;
97eeb4d9 188 /* these get messy on amd64 due to alignment differences */
bf0a199b 189#if defined(CONFIG_X86_64)
3e63cbb1
AJ
190 case FS_IOC_RESVSP_32:
191 case FS_IOC_RESVSP64_32:
837a6e7f
CH
192 error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
193 goto out_fput;
194 case FS_IOC_UNRESVSP_32:
195 case FS_IOC_UNRESVSP64_32:
196 error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
197 compat_ptr(arg));
198 goto out_fput;
199 case FS_IOC_ZERO_RANGE_32:
200 error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
201 compat_ptr(arg));
3e63cbb1
AJ
202 goto out_fput;
203#else
204 case FS_IOC_RESVSP:
205 case FS_IOC_RESVSP64:
837a6e7f
CH
206 case FS_IOC_UNRESVSP:
207 case FS_IOC_UNRESVSP64:
837a6e7f 208 case FS_IOC_ZERO_RANGE:
6b2daec1 209 goto found_handler;
37ecf8b2 210#endif
6272e266
CH
211
212 default:
72c2d531 213 if (f.file->f_op->compat_ioctl) {
2903ff01 214 error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
6272e266
CH
215 if (error != -ENOIOCTLCMD)
216 goto out_fput;
217 }
218
72c2d531 219 if (!f.file->f_op->unlocked_ioctl)
6272e266
CH
220 goto do_ioctl;
221 break;
222 }
223
661f627d
AB
224 if (compat_ioctl_check_table(XFORM(cmd)))
225 goto found_handler;
6272e266 226
66cf191f 227 error = do_ioctl_trans(cmd, arg, f.file);
07d106d0
LT
228 if (error == -ENOIOCTLCMD)
229 error = -ENOTTY;
6272e266
CH
230
231 goto out_fput;
232
233 found_handler:
789f0f89 234 arg = (unsigned long)compat_ptr(arg);
6272e266 235 do_ioctl:
2903ff01 236 error = do_vfs_ioctl(f.file, fd, cmd, arg);
6272e266 237 out_fput:
2903ff01 238 fdput(f);
6272e266
CH
239 out:
240 return error;
241}
242
661f627d 243static int __init init_sys32_ioctl_cmp(const void *p, const void *q)
6272e266 244{
661f627d
AB
245 unsigned int a, b;
246 a = *(unsigned int *)p;
247 b = *(unsigned int *)q;
248 if (a > b)
249 return 1;
250 if (a < b)
251 return -1;
252 return 0;
6272e266
CH
253}
254
255static int __init init_sys32_ioctl(void)
256{
661f627d
AB
257 sort(ioctl_pointer, ARRAY_SIZE(ioctl_pointer), sizeof(*ioctl_pointer),
258 init_sys32_ioctl_cmp, NULL);
6272e266
CH
259 return 0;
260}
261__initcall(init_sys32_ioctl);
This page took 1.049173 seconds and 4 git commands to generate.