Blame view

fs/compat_ioctl.c 31 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
  /*
   * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
   *
   * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
   * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
   * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs 
a2531293d   Pavel Machek   update email address
8
   * Copyright (C) 2003       Pavel Machek (pavel@ucw.cz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
   *
   * These routines maintain argument size conversion between 32bit and 64bit
   * ioctls.
   */
3fee37c1e   Akos Maroy   fix: using joysti...
13
  #include <linux/joystick.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
  #include <linux/types.h>
  #include <linux/compat.h>
  #include <linux/kernel.h>
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
17
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
  #include <linux/compiler.h>
  #include <linux/sched.h>
  #include <linux/smp.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
  #include <linux/ioctl.h>
  #include <linux/if.h>
bff61975b   NeilBrown   md: move lots of ...
23
  #include <linux/raid/md_u.h>
3e63cbb1e   Ankit Jain   fs: Add new pre-a...
24
  #include <linux/falloc.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  #include <linux/file.h>
4b32da2bc   Paul Mackerras   ppp: Replace uses...
26
  #include <linux/ppp-ioctl.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
  #include <linux/if_pppox.h>
  #include <linux/mtio.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
  #include <linux/tty.h>
  #include <linux/vt_kern.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
  #include <linux/raw.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  #include <linux/blkdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
  #include <linux/rtc.h>
  #include <linux/pci.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  #include <linux/serial.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  #include <linux/ctype.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
  #include <linux/syscalls.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
38
  #include <linux/gfp.h>
594edf39c   Hans Verkuil   [media] cec: add ...
39
  #include <linux/cec.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40

66cf191f3   Al Viro   compat_ioctl: don...
41
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
  #include <net/bluetooth/bluetooth.h>
f49daa819   Marcel Holtmann   Bluetooth: Move H...
43
  #include <net/bluetooth/hci_sock.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
46
  #include <net/bluetooth/rfcomm.h>
  
  #include <linux/capi.h>
5024ad4af   Hansjoerg Lipp   [PATCH] i4l: Giga...
47
  #include <linux/gigaset_dev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48

3c3622dcb   Randy Dunlap   Fix compile issue...
49
  #ifdef CONFIG_BLOCK
390192b30   Johannes Stezenbach   compat_ioctl: fix...
50
51
  #include <linux/cdrom.h>
  #include <linux/fd.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
  #include <scsi/scsi.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
  #include <scsi/scsi_ioctl.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  #include <scsi/sg.h>
3c3622dcb   Randy Dunlap   Fix compile issue...
55
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56

7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
57
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
  #include <linux/watchdog.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  #include <linux/soundcard.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
  
  #include <linux/hiddev.h>
6e87abd0b   David S. Miller   [DVB]: Add compat...
63

661f627da   Arnd Bergmann   compat_ioctl: sim...
64
  #include <linux/sort.h>
8163904e6   David S. Miller   [SPARC]: Mark SBU...
65
  #ifdef CONFIG_SPARC
0976d4e1d   Al Viro   compat_ioctl: tri...
66
  #include <linux/fb.h>
8163904e6   David S. Miller   [SPARC]: Mark SBU...
67
68
  #include <asm/fbio.h>
  #endif
a7f61e89a   Jann Horn   compat_ioctl: don...
69
70
71
72
73
74
  #define convert_in_user(srcptr, dstptr)			\
  ({							\
  	typeof(*srcptr) val;				\
  							\
  	get_user(val, srcptr) || put_user(val, dstptr);	\
  })
66cf191f3   Al Viro   compat_ioctl: don...
75
  static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
b43417216   Jann Horn   compat_ioctl: don...
76
77
78
79
80
81
  {
  	int err;
  
  	err = security_file_ioctl(file, cmd, arg);
  	if (err)
  		return err;
66cf191f3   Al Viro   compat_ioctl: don...
82
  	return vfs_ioctl(file, cmd, arg);
b43417216   Jann Horn   compat_ioctl: don...
83
  }
9361401eb   David Howells   [PATCH] BLOCK: Ma...
84
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  typedef struct sg_io_hdr32 {
  	compat_int_t interface_id;	/* [i] 'S' for SCSI generic (required) */
  	compat_int_t dxfer_direction;	/* [i] data transfer direction  */
  	unsigned char cmd_len;		/* [i] SCSI command length ( <= 16 bytes) */
  	unsigned char mx_sb_len;		/* [i] max length to write to sbp */
  	unsigned short iovec_count;	/* [i] 0 implies no scatter gather */
  	compat_uint_t dxfer_len;		/* [i] byte count of data transfer */
  	compat_uint_t dxferp;		/* [i], [*io] points to data transfer memory
  					      or scatter gather list */
  	compat_uptr_t cmdp;		/* [i], [*i] points to command to perform */
  	compat_uptr_t sbp;		/* [i], [*o] points to sense_buffer memory */
  	compat_uint_t timeout;		/* [i] MAX_UINT->no timeout (unit: millisec) */
  	compat_uint_t flags;		/* [i] 0 -> default, see SG_FLAG... */
  	compat_int_t pack_id;		/* [i->o] unused internally (normally) */
  	compat_uptr_t usr_ptr;		/* [i->o] unused internally */
  	unsigned char status;		/* [o] scsi status */
  	unsigned char masked_status;	/* [o] shifted, masked scsi status */
  	unsigned char msg_status;		/* [o] messaging level data (optional) */
  	unsigned char sb_len_wr;		/* [o] byte count actually written to sbp */
  	unsigned short host_status;	/* [o] errors from host adapter */
  	unsigned short driver_status;	/* [o] errors from software driver */
  	compat_int_t resid;		/* [o] dxfer_len - actual_transferred */
  	compat_uint_t duration;		/* [o] time taken by cmd (unit: millisec) */
  	compat_uint_t info;		/* [o] auxiliary information */
  } sg_io_hdr32_t;  /* 64 bytes long (on sparc32) */
  
  typedef struct sg_iovec32 {
  	compat_uint_t iov_base;
  	compat_uint_t iov_len;
  } sg_iovec32_t;
  
  static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count)
  {
  	sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1);
  	sg_iovec32_t __user *iov32 = dxferp;
  	int i;
  
  	for (i = 0; i < iovec_count; i++) {
  		u32 base, len;
  
  		if (get_user(base, &iov32[i].iov_base) ||
  		    get_user(len, &iov32[i].iov_len) ||
  		    put_user(compat_ptr(base), &iov[i].iov_base) ||
  		    put_user(len, &iov[i].iov_len))
  			return -EFAULT;
  	}
  
  	if (put_user(iov, &sgio->dxferp))
  		return -EFAULT;
  	return 0;
  }
66cf191f3   Al Viro   compat_ioctl: don...
136
  static int sg_ioctl_trans(struct file *file, unsigned int cmd,
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
137
  			sg_io_hdr32_t __user *sgio32)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
  {
  	sg_io_hdr_t __user *sgio;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
143
  	u16 iovec_count;
  	u32 data;
  	void __user *dxferp;
  	int err;
84eb8fb42   FUJITA Tomonori   [SCSI] compat_ioc...
144
145
146
147
148
  	int interface_id;
  
  	if (get_user(interface_id, &sgio32->interface_id))
  		return -EFAULT;
  	if (interface_id != 'S')
66cf191f3   Al Viro   compat_ioctl: don...
149
  		return do_ioctl(file, cmd, (unsigned long)sgio32);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  	if (get_user(iovec_count, &sgio32->iovec_count))
  		return -EFAULT;
  
  	{
  		void __user *top = compat_alloc_user_space(0);
  		void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) +
  				       (iovec_count * sizeof(sg_iovec_t)));
  		if (new > top)
  			return -EINVAL;
  
  		sgio = new;
  	}
  
  	/* Ok, now construct.  */
  	if (copy_in_user(&sgio->interface_id, &sgio32->interface_id,
  			 (2 * sizeof(int)) +
  			 (2 * sizeof(unsigned char)) +
  			 (1 * sizeof(unsigned short)) +
  			 (1 * sizeof(unsigned int))))
  		return -EFAULT;
  
  	if (get_user(data, &sgio32->dxferp))
  		return -EFAULT;
  	dxferp = compat_ptr(data);
  	if (iovec_count) {
  		if (sg_build_iovec(sgio, dxferp, iovec_count))
  			return -EFAULT;
  	} else {
  		if (put_user(dxferp, &sgio->dxferp))
  			return -EFAULT;
  	}
  
  	{
  		unsigned char __user *cmdp;
  		unsigned char __user *sbp;
  
  		if (get_user(data, &sgio32->cmdp))
  			return -EFAULT;
  		cmdp = compat_ptr(data);
  
  		if (get_user(data, &sgio32->sbp))
  			return -EFAULT;
  		sbp = compat_ptr(data);
  
  		if (put_user(cmdp, &sgio->cmdp) ||
  		    put_user(sbp, &sgio->sbp))
  			return -EFAULT;
  	}
  
  	if (copy_in_user(&sgio->timeout, &sgio32->timeout,
  			 3 * sizeof(int)))
  		return -EFAULT;
  
  	if (get_user(data, &sgio32->usr_ptr))
  		return -EFAULT;
  	if (put_user(compat_ptr(data), &sgio->usr_ptr))
  		return -EFAULT;
66cf191f3   Al Viro   compat_ioctl: don...
208
  	err = do_ioctl(file, cmd, (unsigned long) sgio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  
  	if (err >= 0) {
  		void __user *datap;
  
  		if (copy_in_user(&sgio32->pack_id, &sgio->pack_id,
  				 sizeof(int)) ||
  		    get_user(datap, &sgio->usr_ptr) ||
  		    put_user((u32)(unsigned long)datap,
  			     &sgio32->usr_ptr) ||
  		    copy_in_user(&sgio32->status, &sgio->status,
  				 (4 * sizeof(unsigned char)) +
  				 (2 * sizeof(unsigned short)) +
  				 (3 * sizeof(int))))
  			err = -EFAULT;
  	}
  
  	return err;
  }
2966387b4   Andi Kleen   [PATCH] x86_64: I...
227
228
229
230
231
232
233
234
235
236
  struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
  	char req_state;
  	char orphan;
  	char sg_io_owned;
  	char problem;
  	int pack_id;
  	compat_uptr_t usr_ptr;
  	unsigned int duration;
  	int unused;
  };
66cf191f3   Al Viro   compat_ioctl: don...
237
  static int sg_grt_trans(struct file *file,
b43417216   Jann Horn   compat_ioctl: don...
238
  		unsigned int cmd, struct compat_sg_req_info __user *o)
2966387b4   Andi Kleen   [PATCH] x86_64: I...
239
240
  {
  	int err, i;
6b2b4e5a2   Al Viro   [PATCH] compat_io...
241
  	sg_req_info_t __user *r;
2966387b4   Andi Kleen   [PATCH] x86_64: I...
242
  	r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
66cf191f3   Al Viro   compat_ioctl: don...
243
  	err = do_ioctl(file, cmd, (unsigned long)r);
2966387b4   Andi Kleen   [PATCH] x86_64: I...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
  	if (err < 0)
  		return err;
  	for (i = 0; i < SG_MAX_QUEUE; i++) {
  		void __user *ptr;
  		int d;
  
  		if (copy_in_user(o + i, r + i, offsetof(sg_req_info_t, usr_ptr)) ||
  		    get_user(ptr, &r[i].usr_ptr) ||
  		    get_user(d, &r[i].duration) ||
  		    put_user((u32)(unsigned long)(ptr), &o[i].usr_ptr) ||
  		    put_user(d, &o[i].duration))
  			return -EFAULT;
  	}
  	return err;
  }
9361401eb   David Howells   [PATCH] BLOCK: Ma...
259
  #endif /* CONFIG_BLOCK */
2966387b4   Andi Kleen   [PATCH] x86_64: I...
260

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
264
265
266
267
  struct sock_fprog32 {
  	unsigned short	len;
  	compat_caddr_t	filter;
  };
  
  #define PPPIOCSPASS32	_IOW('t', 71, struct sock_fprog32)
  #define PPPIOCSACTIVE32	_IOW('t', 70, struct sock_fprog32)
66cf191f3   Al Viro   compat_ioctl: don...
268
  static int ppp_sock_fprog_ioctl_trans(struct file *file,
b43417216   Jann Horn   compat_ioctl: don...
269
  		unsigned int cmd, struct sock_fprog32 __user *u_fprog32)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  	struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
  	void __user *fptr64;
  	u32 fptr32;
  	u16 flen;
  
  	if (get_user(flen, &u_fprog32->len) ||
  	    get_user(fptr32, &u_fprog32->filter))
  		return -EFAULT;
  
  	fptr64 = compat_ptr(fptr32);
  
  	if (put_user(flen, &u_fprog64->len) ||
  	    put_user(fptr64, &u_fprog64->filter))
  		return -EFAULT;
  
  	if (cmd == PPPIOCSPASS32)
  		cmd = PPPIOCSPASS;
  	else
  		cmd = PPPIOCSACTIVE;
66cf191f3   Al Viro   compat_ioctl: don...
290
  	return do_ioctl(file, cmd, (unsigned long) u_fprog64);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  }
  
  struct ppp_option_data32 {
  	compat_caddr_t	ptr;
  	u32			length;
  	compat_int_t		transmit;
  };
  #define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
  
  struct ppp_idle32 {
  	compat_time_t xmit_idle;
  	compat_time_t recv_idle;
  };
  #define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)
66cf191f3   Al Viro   compat_ioctl: don...
305
  static int ppp_gidle(struct file *file, unsigned int cmd,
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
306
  		struct ppp_idle32 __user *idle32)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
  {
  	struct ppp_idle __user *idle;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
  	__kernel_time_t xmit, recv;
  	int err;
  
  	idle = compat_alloc_user_space(sizeof(*idle));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313

66cf191f3   Al Viro   compat_ioctl: don...
314
  	err = do_ioctl(file, PPPIOCGIDLE, (unsigned long) idle);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
317
318
319
320
321
322
323
324
  
  	if (!err) {
  		if (get_user(xmit, &idle->xmit_idle) ||
  		    get_user(recv, &idle->recv_idle) ||
  		    put_user(xmit, &idle32->xmit_idle) ||
  		    put_user(recv, &idle32->recv_idle))
  			err = -EFAULT;
  	}
  	return err;
  }
66cf191f3   Al Viro   compat_ioctl: don...
325
  static int ppp_scompress(struct file *file, unsigned int cmd,
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
326
  	struct ppp_option_data32 __user *odata32)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
  {
  	struct ppp_option_data __user *odata;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
331
332
  	__u32 data;
  	void __user *datap;
  
  	odata = compat_alloc_user_space(sizeof(*odata));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
334
335
336
337
338
339
340
341
342
343
  
  	if (get_user(data, &odata32->ptr))
  		return -EFAULT;
  
  	datap = compat_ptr(data);
  	if (put_user(datap, &odata->ptr))
  		return -EFAULT;
  
  	if (copy_in_user(&odata->length, &odata32->length,
  			 sizeof(__u32) + sizeof(int)))
  		return -EFAULT;
66cf191f3   Al Viro   compat_ioctl: don...
344
  	return do_ioctl(file, PPPIOCSCOMPRESS, (unsigned long) odata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
  }
9361401eb   David Howells   [PATCH] BLOCK: Ma...
346
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  struct mtget32 {
  	compat_long_t	mt_type;
  	compat_long_t	mt_resid;
  	compat_long_t	mt_dsreg;
  	compat_long_t	mt_gstat;
  	compat_long_t	mt_erreg;
  	compat_daddr_t	mt_fileno;
  	compat_daddr_t	mt_blkno;
  };
  #define MTIOCGET32	_IOR('m', 2, struct mtget32)
  
  struct mtpos32 {
  	compat_long_t	mt_blkno;
  };
  #define MTIOCPOS32	_IOR('m', 3, struct mtpos32)
66cf191f3   Al Viro   compat_ioctl: don...
362
  static int mt_ioctl_trans(struct file *file,
b43417216   Jann Horn   compat_ioctl: don...
363
  		unsigned int cmd, void __user *argp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
  {
a7f61e89a   Jann Horn   compat_ioctl: don...
365
366
  	/* NULL initialization to make gcc shut up */
  	struct mtget __user *get = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
  	struct mtget32 __user *umget32;
a7f61e89a   Jann Horn   compat_ioctl: don...
368
  	struct mtpos __user *pos = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
371
372
373
374
375
376
  	struct mtpos32 __user *upos32;
  	unsigned long kcmd;
  	void *karg;
  	int err = 0;
  
  	switch(cmd) {
  	case MTIOCPOS32:
  		kcmd = MTIOCPOS;
a7f61e89a   Jann Horn   compat_ioctl: don...
377
378
  		pos = compat_alloc_user_space(sizeof(*pos));
  		karg = pos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
  		break;
45bf5cd7b   Andrew Morton   fs/compat_ioctl.c...
380
  	default:	/* MTIOCGET32 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381
  		kcmd = MTIOCGET;
a7f61e89a   Jann Horn   compat_ioctl: don...
382
383
  		get = compat_alloc_user_space(sizeof(*get));
  		karg = get;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  	}
a7f61e89a   Jann Horn   compat_ioctl: don...
386
387
  	if (karg == NULL)
  		return -EFAULT;
66cf191f3   Al Viro   compat_ioctl: don...
388
  	err = do_ioctl(file, kcmd, (unsigned long)karg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
391
392
  	if (err)
  		return err;
  	switch (cmd) {
  	case MTIOCPOS32:
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
393
  		upos32 = argp;
a7f61e89a   Jann Horn   compat_ioctl: don...
394
  		err = convert_in_user(&pos->mt_blkno, &upos32->mt_blkno);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
  		break;
  	case MTIOCGET32:
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
397
  		umget32 = argp;
a7f61e89a   Jann Horn   compat_ioctl: don...
398
399
400
401
402
403
404
  		err = convert_in_user(&get->mt_type, &umget32->mt_type);
  		err |= convert_in_user(&get->mt_resid, &umget32->mt_resid);
  		err |= convert_in_user(&get->mt_dsreg, &umget32->mt_dsreg);
  		err |= convert_in_user(&get->mt_gstat, &umget32->mt_gstat);
  		err |= convert_in_user(&get->mt_erreg, &umget32->mt_erreg);
  		err |= convert_in_user(&get->mt_fileno, &umget32->mt_fileno);
  		err |= convert_in_user(&get->mt_blkno, &umget32->mt_blkno);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
406
407
408
  		break;
  	}
  	return err ? -EFAULT: 0;
  }
9361401eb   David Howells   [PATCH] BLOCK: Ma...
409
  #endif /* CONFIG_BLOCK */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
  /* Bluetooth ioctls */
2cdf096ff   Johan Hedberg   Bluetooth: Add mi...
412
413
414
  #define HCIUARTSETPROTO		_IOW('U', 200, int)
  #define HCIUARTGETPROTO		_IOR('U', 201, int)
  #define HCIUARTGETDEVICE	_IOR('U', 202, int)
63c7d09cd   Johan Hedberg   Bluetooth: Add HC...
415
416
  #define HCIUARTSETFLAGS		_IOW('U', 203, int)
  #define HCIUARTGETFLAGS		_IOR('U', 204, int)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417

ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
418
419
420
421
  #define RTC_IRQP_READ32		_IOR('p', 0x0b, compat_ulong_t)
  #define RTC_IRQP_SET32		_IOW('p', 0x0c, compat_ulong_t)
  #define RTC_EPOCH_READ32	_IOR('p', 0x0d, compat_ulong_t)
  #define RTC_EPOCH_SET32		_IOW('p', 0x0e, compat_ulong_t)
66cf191f3   Al Viro   compat_ioctl: don...
422
  static int rtc_ioctl(struct file *file,
b43417216   Jann Horn   compat_ioctl: don...
423
  		unsigned cmd, void __user *argp)
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
424
  {
a7f61e89a   Jann Horn   compat_ioctl: don...
425
  	unsigned long __user *valp = compat_alloc_user_space(sizeof(*valp));
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
426
  	int ret;
a7f61e89a   Jann Horn   compat_ioctl: don...
427
428
  	if (valp == NULL)
  		return -EFAULT;
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
429
430
431
  	switch (cmd) {
  	case RTC_IRQP_READ32:
  	case RTC_EPOCH_READ32:
66cf191f3   Al Viro   compat_ioctl: don...
432
  		ret = do_ioctl(file, (cmd == RTC_IRQP_READ32) ?
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
433
  					RTC_IRQP_READ : RTC_EPOCH_READ,
a7f61e89a   Jann Horn   compat_ioctl: don...
434
  					(unsigned long)valp);
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
435
436
  		if (ret)
  			return ret;
a7f61e89a   Jann Horn   compat_ioctl: don...
437
  		return convert_in_user(valp, (unsigned int __user *)argp);
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
438
  	case RTC_IRQP_SET32:
66cf191f3   Al Viro   compat_ioctl: don...
439
  		return do_ioctl(file, RTC_IRQP_SET, (unsigned long)argp);
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
440
  	case RTC_EPOCH_SET32:
66cf191f3   Al Viro   compat_ioctl: don...
441
  		return do_ioctl(file, RTC_EPOCH_SET, (unsigned long)argp);
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
442
  	}
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
443
444
  
  	return -ENOIOCTLCMD;
ec3cad969   Christoph Hellwig   [PATCH] move rtc ...
445
  }
3e63cbb1e   Ankit Jain   fs: Add new pre-a...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
  /* on ia32 l_start is on a 32-bit boundary */
  #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
  struct space_resv_32 {
  	__s16		l_type;
  	__s16		l_whence;
  	__s64		l_start	__attribute__((packed));
  			/* len == 0 means until end of file */
  	__s64		l_len __attribute__((packed));
  	__s32		l_sysid;
  	__u32		l_pid;
  	__s32		l_pad[4];	/* reserve area */
  };
  
  #define FS_IOC_RESVSP_32		_IOW ('X', 40, struct space_resv_32)
  #define FS_IOC_RESVSP64_32	_IOW ('X', 42, struct space_resv_32)
  
  /* just account for different alignment */
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
463
464
  static int compat_ioctl_preallocate(struct file *file,
  			struct space_resv_32    __user *p32)
3e63cbb1e   Ankit Jain   fs: Add new pre-a...
465
  {
3e63cbb1e   Ankit Jain   fs: Add new pre-a...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
  	struct space_resv	__user *p = compat_alloc_user_space(sizeof(*p));
  
  	if (copy_in_user(&p->l_type,	&p32->l_type,	sizeof(s16)) ||
  	    copy_in_user(&p->l_whence,	&p32->l_whence, sizeof(s16)) ||
  	    copy_in_user(&p->l_start,	&p32->l_start,	sizeof(s64)) ||
  	    copy_in_user(&p->l_len,	&p32->l_len,	sizeof(s64)) ||
  	    copy_in_user(&p->l_sysid,	&p32->l_sysid,	sizeof(s32)) ||
  	    copy_in_user(&p->l_pid,	&p32->l_pid,	sizeof(u32)) ||
  	    copy_in_user(&p->l_pad,	&p32->l_pad,	4*sizeof(u32)))
  		return -EFAULT;
  
  	return ioctl_preallocate(file, p);
  }
  #endif
661f627da   Arnd Bergmann   compat_ioctl: sim...
480
481
482
483
484
  /*
   * simple reversible transform to make our table more evenly
   * distributed after sorting.
   */
  #define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff)
6272e2667   Christoph Hellwig   cleanup compat io...
485

9280cdd6f   Mark Charlebois   fs: compat: Remov...
486
  #define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd),
421f02810   Andi Kleen   [PATCH] x86-64: D...
487
488
489
490
491
492
493
494
  /* ioctl should not be warned about even if it's not implemented.
     Valid reasons to use this:
     - It is implemented with ->compat_ioctl on some device, but programs
     call it on others too.
     - The ioctl is not implemented in the native kernel, but programs
     call it commonly anyways.
     Most other reasons are not valid. */
  #define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd)
e6a6d2efc   Christoph Hellwig   [PATCH] sanitize ...
495

661f627da   Arnd Bergmann   compat_ioctl: sim...
496
  static unsigned int ioctl_pointer[] = {
644fd4f5d   Christoph Hellwig   merge compat_ioct...
497
  /* compatible ioctls first */
644fd4f5d   Christoph Hellwig   merge compat_ioct...
498
  /* Little t */
644fd4f5d   Christoph Hellwig   merge compat_ioct...
499
  COMPATIBLE_IOCTL(TIOCOUTQ)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
500
501
502
503
504
505
  /* Little f */
  COMPATIBLE_IOCTL(FIOCLEX)
  COMPATIBLE_IOCTL(FIONCLEX)
  COMPATIBLE_IOCTL(FIOASYNC)
  COMPATIBLE_IOCTL(FIONBIO)
  COMPATIBLE_IOCTL(FIONREAD)  /* This is also TIOCINQ */
69130c7cf   Eric Sandeen   compat_ioctl: hoo...
506
  COMPATIBLE_IOCTL(FS_IOC_FIEMAP)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
507
508
509
  /* 0x00 */
  COMPATIBLE_IOCTL(FIBMAP)
  COMPATIBLE_IOCTL(FIGETBSZ)
5cf8cf414   Christoph Hellwig   Fix FREEZE/THAW c...
510
511
512
  /* 'X' - originally XFS but some now in the VFS */
  COMPATIBLE_IOCTL(FIFREEZE)
  COMPATIBLE_IOCTL(FITHAW)
9abea2d64   Mikulas Patocka   ioctl_compat: han...
513
  COMPATIBLE_IOCTL(FITRIM)
3c3622dcb   Randy Dunlap   Fix compile issue...
514
  #ifdef CONFIG_BLOCK
644fd4f5d   Christoph Hellwig   merge compat_ioct...
515
516
517
518
519
520
521
522
523
  /* Big S */
  COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
  COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
  COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
  COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
  COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
  COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
  COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
  COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
3c3622dcb   Randy Dunlap   Fix compile issue...
524
  #endif
3f0017112   Atsushi Nemoto   compat_ioctl: Sup...
525
526
527
  /* Big V (don't complain on serial console) */
  IGNORE_IOCTL(VT_OPENQRY)
  IGNORE_IOCTL(VT_GETMODE)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
  /* Little p (/dev/rtc, /dev/envctrl, etc.) */
  COMPATIBLE_IOCTL(RTC_AIE_ON)
  COMPATIBLE_IOCTL(RTC_AIE_OFF)
  COMPATIBLE_IOCTL(RTC_UIE_ON)
  COMPATIBLE_IOCTL(RTC_UIE_OFF)
  COMPATIBLE_IOCTL(RTC_PIE_ON)
  COMPATIBLE_IOCTL(RTC_PIE_OFF)
  COMPATIBLE_IOCTL(RTC_WIE_ON)
  COMPATIBLE_IOCTL(RTC_WIE_OFF)
  COMPATIBLE_IOCTL(RTC_ALM_SET)
  COMPATIBLE_IOCTL(RTC_ALM_READ)
  COMPATIBLE_IOCTL(RTC_RD_TIME)
  COMPATIBLE_IOCTL(RTC_SET_TIME)
  COMPATIBLE_IOCTL(RTC_WKALM_SET)
  COMPATIBLE_IOCTL(RTC_WKALM_RD)
  /*
   * These two are only for the sbus rtc driver, but
   * hwclock tries them on every rtc device first when
   * running on sparc.  On other architectures the entries
   * are useless but harmless.
   */
  COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
  COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
  /* Little m */
  COMPATIBLE_IOCTL(MTIOCTOP)
  /* Socket level stuff */
  COMPATIBLE_IOCTL(FIOQSIZE)
3c3622dcb   Randy Dunlap   Fix compile issue...
555
  #ifdef CONFIG_BLOCK
f79f11852   Arnd Bergmann   compat_ioctl: ign...
556
557
  /* md calls this on random blockdevs */
  IGNORE_IOCTL(RAID_VERSION)
390192b30   Johannes Stezenbach   compat_ioctl: fix...
558
559
560
  /* qemu/qemu-img might call these two on plain files for probing */
  IGNORE_IOCTL(CDROM_DRIVE_STATUS)
  IGNORE_IOCTL(FDGETPRM32)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
561
562
563
564
  /* SG stuff */
  COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
  COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
  COMPATIBLE_IOCTL(SG_EMULATED_HOST)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
  COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
  COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
  COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
  COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
  COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
  COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
  COMPATIBLE_IOCTL(SG_GET_PACK_ID)
  COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
  COMPATIBLE_IOCTL(SG_SET_DEBUG)
  COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
  COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
  COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
  COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
  COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
  COMPATIBLE_IOCTL(SG_SCSI_RESET)
  COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
  COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
  COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
3c3622dcb   Randy Dunlap   Fix compile issue...
584
  #endif
644fd4f5d   Christoph Hellwig   merge compat_ioct...
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
  /* PPP stuff */
  COMPATIBLE_IOCTL(PPPIOCGFLAGS)
  COMPATIBLE_IOCTL(PPPIOCSFLAGS)
  COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
  COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
  COMPATIBLE_IOCTL(PPPIOCGUNIT)
  COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
  COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
  COMPATIBLE_IOCTL(PPPIOCGMRU)
  COMPATIBLE_IOCTL(PPPIOCSMRU)
  COMPATIBLE_IOCTL(PPPIOCSMAXCID)
  COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
  COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
  COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
  /* PPPIOCSCOMPRESS is translated */
  COMPATIBLE_IOCTL(PPPIOCGNPMODE)
  COMPATIBLE_IOCTL(PPPIOCSNPMODE)
  COMPATIBLE_IOCTL(PPPIOCGDEBUG)
  COMPATIBLE_IOCTL(PPPIOCSDEBUG)
  /* PPPIOCSPASS is translated */
  /* PPPIOCSACTIVE is translated */
  /* PPPIOCGIDLE is translated */
  COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
  COMPATIBLE_IOCTL(PPPIOCATTACH)
  COMPATIBLE_IOCTL(PPPIOCDETACH)
  COMPATIBLE_IOCTL(PPPIOCSMRRU)
  COMPATIBLE_IOCTL(PPPIOCCONNECT)
  COMPATIBLE_IOCTL(PPPIOCDISCONN)
  COMPATIBLE_IOCTL(PPPIOCATTCHAN)
  COMPATIBLE_IOCTL(PPPIOCGCHAN)
8bab6f140   Florian Westphal   compat_ioctl: add...
615
  COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
  /* Big A */
  /* sparc only */
  /* Big Q for sound/OSS */
  COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
  COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
  COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
  COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
  COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
  COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
  COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
  COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
  COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
  COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
  /* Big T for sound/OSS */
  COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
  COMPATIBLE_IOCTL(SNDCTL_TMR_START)
  COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
  COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
  COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
  COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
  COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
  COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
  /* Little m for sound/OSS */
  COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
  COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
  COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
  /* Big P for sound/OSS */
  COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
  COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
  COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
  COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
  COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
  COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
  COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
  COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
  COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
  COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
  COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
  COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
  /* SNDCTL_DSP_MAPINBUF,  XXX needs translation */
  /* SNDCTL_DSP_MAPOUTBUF,  XXX needs translation */
  COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
  COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
  COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
  COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
  COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
  COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
  COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
  COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
  /* Big C for sound/OSS */
  COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
  COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
  COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
  COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
  COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
  COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
  COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
  COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
  COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
  COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
  /* Big M for sound/OSS */
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
  COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE)
  /* SOUND_MIXER_READ_ENHANCE,  same value as READ_MUTE */
  /* SOUND_MIXER_READ_LOUD,  same value as READ_MUTE */
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
  COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
  COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
  /* SOUND_MIXER_WRITE_ENHANCE,  same value as WRITE_MUTE */
  /* SOUND_MIXER_WRITE_LOUD,  same value as WRITE_MUTE */
  COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
  COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
  COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
  COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
  COMPATIBLE_IOCTL(SOUND_MIXER_AGC)
  COMPATIBLE_IOCTL(SOUND_MIXER_3DSE)
  COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
  COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
  COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
  COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
  COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
  COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
  COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
  COMPATIBLE_IOCTL(OSS_GETVERSION)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
772
773
774
  /* Raw devices */
  COMPATIBLE_IOCTL(RAW_SETBIND)
  COMPATIBLE_IOCTL(RAW_GETBIND)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
775
776
777
778
779
780
781
782
783
  /* Watchdog */
  COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
  COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
  COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
  COMPATIBLE_IOCTL(WDIOC_GETTEMP)
  COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
  COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
  COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT)
  COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT)
97beb3ae0   Wolfram Sang   fs: compat_ioctl:...
784
785
  COMPATIBLE_IOCTL(WDIOC_SETPRETIMEOUT)
  COMPATIBLE_IOCTL(WDIOC_GETPRETIMEOUT)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
  /* Big R */
  COMPATIBLE_IOCTL(RNDGETENTCNT)
  COMPATIBLE_IOCTL(RNDADDTOENTCNT)
  COMPATIBLE_IOCTL(RNDGETPOOL)
  COMPATIBLE_IOCTL(RNDADDENTROPY)
  COMPATIBLE_IOCTL(RNDZAPENTCNT)
  COMPATIBLE_IOCTL(RNDCLEARPOOL)
  /* Bluetooth */
  COMPATIBLE_IOCTL(HCIDEVUP)
  COMPATIBLE_IOCTL(HCIDEVDOWN)
  COMPATIBLE_IOCTL(HCIDEVRESET)
  COMPATIBLE_IOCTL(HCIDEVRESTAT)
  COMPATIBLE_IOCTL(HCIGETDEVLIST)
  COMPATIBLE_IOCTL(HCIGETDEVINFO)
  COMPATIBLE_IOCTL(HCIGETCONNLIST)
  COMPATIBLE_IOCTL(HCIGETCONNINFO)
40be492fe   Marcel Holtmann   [Bluetooth] Expor...
802
  COMPATIBLE_IOCTL(HCIGETAUTHINFO)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
803
804
805
806
807
808
809
810
811
  COMPATIBLE_IOCTL(HCISETRAW)
  COMPATIBLE_IOCTL(HCISETSCAN)
  COMPATIBLE_IOCTL(HCISETAUTH)
  COMPATIBLE_IOCTL(HCISETENCRYPT)
  COMPATIBLE_IOCTL(HCISETPTYPE)
  COMPATIBLE_IOCTL(HCISETLINKPOL)
  COMPATIBLE_IOCTL(HCISETLINKMODE)
  COMPATIBLE_IOCTL(HCISETACLMTU)
  COMPATIBLE_IOCTL(HCISETSCOMTU)
f03585689   Johan Hedberg   Bluetooth: Add bl...
812
813
  COMPATIBLE_IOCTL(HCIBLOCKADDR)
  COMPATIBLE_IOCTL(HCIUNBLOCKADDR)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
814
815
816
  COMPATIBLE_IOCTL(HCIINQUIRY)
  COMPATIBLE_IOCTL(HCIUARTSETPROTO)
  COMPATIBLE_IOCTL(HCIUARTGETPROTO)
d10d34aa7   Marcel Holtmann   Bluetooth: Add mi...
817
818
819
  COMPATIBLE_IOCTL(HCIUARTGETDEVICE)
  COMPATIBLE_IOCTL(HCIUARTSETFLAGS)
  COMPATIBLE_IOCTL(HCIUARTGETFLAGS)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
820
821
822
823
824
  COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
  COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
  COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
  COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
  COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
  /* CAPI */
  COMPATIBLE_IOCTL(CAPI_REGISTER)
  COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
  COMPATIBLE_IOCTL(CAPI_GET_VERSION)
  COMPATIBLE_IOCTL(CAPI_GET_SERIAL)
  COMPATIBLE_IOCTL(CAPI_GET_PROFILE)
  COMPATIBLE_IOCTL(CAPI_MANUFACTURER_CMD)
  COMPATIBLE_IOCTL(CAPI_GET_ERRCODE)
  COMPATIBLE_IOCTL(CAPI_INSTALLED)
  COMPATIBLE_IOCTL(CAPI_GET_FLAGS)
  COMPATIBLE_IOCTL(CAPI_SET_FLAGS)
  COMPATIBLE_IOCTL(CAPI_CLR_FLAGS)
  COMPATIBLE_IOCTL(CAPI_NCCI_OPENCOUNT)
  COMPATIBLE_IOCTL(CAPI_NCCI_GETUNIT)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
839
840
841
842
843
844
845
  /* Misc. */
  COMPATIBLE_IOCTL(0x41545900)		/* ATYIO_CLKR */
  COMPATIBLE_IOCTL(0x41545901)		/* ATYIO_CLKW */
  COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
  COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
  COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
  COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
644fd4f5d   Christoph Hellwig   merge compat_ioct...
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
  /* hiddev */
  COMPATIBLE_IOCTL(HIDIOCGVERSION)
  COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
  COMPATIBLE_IOCTL(HIDIOCGDEVINFO)
  COMPATIBLE_IOCTL(HIDIOCGSTRING)
  COMPATIBLE_IOCTL(HIDIOCINITREPORT)
  COMPATIBLE_IOCTL(HIDIOCGREPORT)
  COMPATIBLE_IOCTL(HIDIOCSREPORT)
  COMPATIBLE_IOCTL(HIDIOCGREPORTINFO)
  COMPATIBLE_IOCTL(HIDIOCGFIELDINFO)
  COMPATIBLE_IOCTL(HIDIOCGUSAGE)
  COMPATIBLE_IOCTL(HIDIOCSUSAGE)
  COMPATIBLE_IOCTL(HIDIOCGUCODE)
  COMPATIBLE_IOCTL(HIDIOCGFLAG)
  COMPATIBLE_IOCTL(HIDIOCSFLAG)
  COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
  COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
3fee37c1e   Akos Maroy   fix: using joysti...
863
864
865
866
867
  /* joystick */
  COMPATIBLE_IOCTL(JSIOCGVERSION)
  COMPATIBLE_IOCTL(JSIOCGAXES)
  COMPATIBLE_IOCTL(JSIOCGBUTTONS)
  COMPATIBLE_IOCTL(JSIOCGNAME(0))
2724b6db6   Andi Kleen   [PATCH] x86-64: S...
868
869
870
871
872
873
874
875
  /* fat 'r' ioctls. These are handled by fat with ->compat_ioctl,
     but we don't want warnings on other file systems. So declare
     them as compatible here. */
  #define VFAT_IOCTL_READDIR_BOTH32       _IOR('r', 1, struct compat_dirent[2])
  #define VFAT_IOCTL_READDIR_SHORT32      _IOR('r', 2, struct compat_dirent[2])
  
  IGNORE_IOCTL(VFAT_IOCTL_READDIR_BOTH32)
  IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32)
98701dc19   Geert Uytterhoeven   compat32: ignore ...
876

8163904e6   David S. Miller   [SPARC]: Mark SBU...
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
  #ifdef CONFIG_SPARC
  /* Sparc framebuffers, handled in sbusfb_compat_ioctl() */
  IGNORE_IOCTL(FBIOGTYPE)
  IGNORE_IOCTL(FBIOSATTR)
  IGNORE_IOCTL(FBIOGATTR)
  IGNORE_IOCTL(FBIOSVIDEO)
  IGNORE_IOCTL(FBIOGVIDEO)
  IGNORE_IOCTL(FBIOSCURPOS)
  IGNORE_IOCTL(FBIOGCURPOS)
  IGNORE_IOCTL(FBIOGCURMAX)
  IGNORE_IOCTL(FBIOPUTCMAP32)
  IGNORE_IOCTL(FBIOGETCMAP32)
  IGNORE_IOCTL(FBIOSCURSOR32)
  IGNORE_IOCTL(FBIOGCURSOR32)
  #endif
e6a6d2efc   Christoph Hellwig   [PATCH] sanitize ...
892
  };
6e87abd0b   David S. Miller   [DVB]: Add compat...
893

5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
894
895
896
897
898
899
900
  /*
   * Convert common ioctl arguments based on their command number
   *
   * Please do not add any code in here. Instead, implement
   * a compat_ioctl operation in the place that handleѕ the
   * ioctl for the native case.
   */
66cf191f3   Al Viro   compat_ioctl: don...
901
  static long do_ioctl_trans(unsigned int cmd,
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
902
903
  		 unsigned long arg, struct file *file)
  {
43c6e7b97   Arnd Bergmann   compat_ioctl: pas...
904
  	void __user *argp = compat_ptr(arg);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
905
906
  	switch (cmd) {
  	case PPPIOCGIDLE32:
66cf191f3   Al Viro   compat_ioctl: don...
907
  		return ppp_gidle(file, cmd, argp);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
908
  	case PPPIOCSCOMPRESS32:
66cf191f3   Al Viro   compat_ioctl: don...
909
  		return ppp_scompress(file, cmd, argp);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
910
911
  	case PPPIOCSPASS32:
  	case PPPIOCSACTIVE32:
66cf191f3   Al Viro   compat_ioctl: don...
912
  		return ppp_sock_fprog_ioctl_trans(file, cmd, argp);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
913
914
  #ifdef CONFIG_BLOCK
  	case SG_IO:
66cf191f3   Al Viro   compat_ioctl: don...
915
  		return sg_ioctl_trans(file, cmd, argp);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
916
  	case SG_GET_REQUEST_TABLE:
66cf191f3   Al Viro   compat_ioctl: don...
917
  		return sg_grt_trans(file, cmd, argp);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
918
919
  	case MTIOCGET32:
  	case MTIOCPOS32:
66cf191f3   Al Viro   compat_ioctl: don...
920
  		return mt_ioctl_trans(file, cmd, argp);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
921
  #endif
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
922
923
924
925
926
  	/* Not implemented in the native kernel */
  	case RTC_IRQP_READ32:
  	case RTC_IRQP_SET32:
  	case RTC_EPOCH_READ32:
  	case RTC_EPOCH_SET32:
66cf191f3   Al Viro   compat_ioctl: don...
927
  		return rtc_ioctl(file, cmd, argp);
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
928
  	}
789f0f891   Arnd Bergmann   compat_ioctl: sim...
929
930
931
932
933
934
  
  	/*
  	 * These take an integer instead of a pointer as 'arg',
  	 * so we must not do a compat_ptr() translation.
  	 */
  	switch (cmd) {
789f0f891   Arnd Bergmann   compat_ioctl: sim...
935
936
937
938
939
  	/* RAID */
  	case HOT_REMOVE_DISK:
  	case HOT_ADD_DISK:
  	case SET_DISK_FAULTY:
  	case SET_BITMAP_FILE:
66cf191f3   Al Viro   compat_ioctl: don...
940
  		return vfs_ioctl(file, cmd, arg);
789f0f891   Arnd Bergmann   compat_ioctl: sim...
941
  	}
5a07ea0b9   Arnd Bergmann   compat_ioctl: inl...
942
943
  	return -ENOIOCTLCMD;
  }
661f627da   Arnd Bergmann   compat_ioctl: sim...
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
  static int compat_ioctl_check_table(unsigned int xcmd)
  {
  	int i;
  	const int max = ARRAY_SIZE(ioctl_pointer) - 1;
  
  	BUILD_BUG_ON(max >= (1 << 16));
  
  	/* guess initial offset into table, assuming a
  	   normalized distribution */
  	i = ((xcmd >> 16) * max) >> 16;
  
  	/* do linear search up first, until greater or equal */
  	while (ioctl_pointer[i] < xcmd && i < max)
  		i++;
  
  	/* then do linear search down */
  	while (ioctl_pointer[i] > xcmd && i > 0)
  		i--;
  
  	return ioctl_pointer[i] == xcmd;
  }
932602e23   Heiko Carstens   fs/compat: conver...
965
966
  COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
  		       compat_ulong_t, arg32)
6272e2667   Christoph Hellwig   cleanup compat io...
967
  {
932602e23   Heiko Carstens   fs/compat: conver...
968
  	unsigned long arg = arg32;
2903ff019   Al Viro   switch simple cas...
969
  	struct fd f = fdget(fd);
6272e2667   Christoph Hellwig   cleanup compat io...
970
  	int error = -EBADF;
2903ff019   Al Viro   switch simple cas...
971
  	if (!f.file)
6272e2667   Christoph Hellwig   cleanup compat io...
972
973
974
  		goto out;
  
  	/* RED-PEN how should LSM module know it's handling 32bit? */
2903ff019   Al Viro   switch simple cas...
975
  	error = security_file_ioctl(f.file, cmd, arg);
6272e2667   Christoph Hellwig   cleanup compat io...
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
  	if (error)
  		goto out_fput;
  
  	/*
  	 * To allow the compat_ioctl handlers to be self contained
  	 * we need to check the common ioctls here first.
  	 * Just handle them with the standard handlers below.
  	 */
  	switch (cmd) {
  	case FIOCLEX:
  	case FIONCLEX:
  	case FIONBIO:
  	case FIOASYNC:
  	case FIOQSIZE:
  		break;
3e63cbb1e   Ankit Jain   fs: Add new pre-a...
991
992
993
  #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
  	case FS_IOC_RESVSP_32:
  	case FS_IOC_RESVSP64_32:
2903ff019   Al Viro   switch simple cas...
994
  		error = compat_ioctl_preallocate(f.file, compat_ptr(arg));
3e63cbb1e   Ankit Jain   fs: Add new pre-a...
995
996
997
998
  		goto out_fput;
  #else
  	case FS_IOC_RESVSP:
  	case FS_IOC_RESVSP64:
2903ff019   Al Viro   switch simple cas...
999
  		error = ioctl_preallocate(f.file, compat_ptr(arg));
3e63cbb1e   Ankit Jain   fs: Add new pre-a...
1000
1001
  		goto out_fput;
  #endif
d79bdd52d   Darrick J. Wong   vfs: wire up comp...
1002
  	case FICLONE:
d536e814a   Al Viro   fix compat handli...
1003
  		goto do_ioctl;
d79bdd52d   Darrick J. Wong   vfs: wire up comp...
1004
  	case FICLONERANGE:
54dbc1517   Darrick J. Wong   vfs: hoist the bt...
1005
  	case FIDEDUPERANGE:
ceac204e1   Josef Bacik   fs: make fiemap w...
1006
  	case FS_IOC_FIEMAP:
d536e814a   Al Viro   fix compat handli...
1007
  		goto found_handler;
d79bdd52d   Darrick J. Wong   vfs: wire up comp...
1008

6272e2667   Christoph Hellwig   cleanup compat io...
1009
1010
1011
  	case FIBMAP:
  	case FIGETBSZ:
  	case FIONREAD:
496ad9aa8   Al Viro   new helper: file_...
1012
  		if (S_ISREG(file_inode(f.file)->i_mode))
6272e2667   Christoph Hellwig   cleanup compat io...
1013
1014
1015
1016
  			break;
  		/*FALL THROUGH*/
  
  	default:
72c2d5319   Al Viro   file->f_op is nev...
1017
  		if (f.file->f_op->compat_ioctl) {
2903ff019   Al Viro   switch simple cas...
1018
  			error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
6272e2667   Christoph Hellwig   cleanup compat io...
1019
1020
1021
  			if (error != -ENOIOCTLCMD)
  				goto out_fput;
  		}
72c2d5319   Al Viro   file->f_op is nev...
1022
  		if (!f.file->f_op->unlocked_ioctl)
6272e2667   Christoph Hellwig   cleanup compat io...
1023
1024
1025
  			goto do_ioctl;
  		break;
  	}
661f627da   Arnd Bergmann   compat_ioctl: sim...
1026
1027
  	if (compat_ioctl_check_table(XFORM(cmd)))
  		goto found_handler;
6272e2667   Christoph Hellwig   cleanup compat io...
1028

66cf191f3   Al Viro   compat_ioctl: don...
1029
  	error = do_ioctl_trans(cmd, arg, f.file);
07d106d0a   Linus Torvalds   vfs: fix up ENOIO...
1030
1031
  	if (error == -ENOIOCTLCMD)
  		error = -ENOTTY;
6272e2667   Christoph Hellwig   cleanup compat io...
1032
1033
1034
1035
  
  	goto out_fput;
  
   found_handler:
789f0f891   Arnd Bergmann   compat_ioctl: sim...
1036
  	arg = (unsigned long)compat_ptr(arg);
6272e2667   Christoph Hellwig   cleanup compat io...
1037
   do_ioctl:
2903ff019   Al Viro   switch simple cas...
1038
  	error = do_vfs_ioctl(f.file, fd, cmd, arg);
6272e2667   Christoph Hellwig   cleanup compat io...
1039
   out_fput:
2903ff019   Al Viro   switch simple cas...
1040
  	fdput(f);
6272e2667   Christoph Hellwig   cleanup compat io...
1041
1042
1043
   out:
  	return error;
  }
661f627da   Arnd Bergmann   compat_ioctl: sim...
1044
  static int __init init_sys32_ioctl_cmp(const void *p, const void *q)
6272e2667   Christoph Hellwig   cleanup compat io...
1045
  {
661f627da   Arnd Bergmann   compat_ioctl: sim...
1046
1047
1048
1049
1050
1051
1052
1053
  	unsigned int a, b;
  	a = *(unsigned int *)p;
  	b = *(unsigned int *)q;
  	if (a > b)
  		return 1;
  	if (a < b)
  		return -1;
  	return 0;
6272e2667   Christoph Hellwig   cleanup compat io...
1054
1055
1056
1057
  }
  
  static int __init init_sys32_ioctl(void)
  {
661f627da   Arnd Bergmann   compat_ioctl: sim...
1058
1059
  	sort(ioctl_pointer, ARRAY_SIZE(ioctl_pointer), sizeof(*ioctl_pointer),
  		init_sys32_ioctl_cmp, NULL);
6272e2667   Christoph Hellwig   cleanup compat io...
1060
1061
1062
  	return 0;
  }
  __initcall(init_sys32_ioctl);