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>
40 #include <linux/cdrom.h>
42 #include <scsi/scsi.h>
43 #include <scsi/scsi_ioctl.h>
47 #include <linux/uaccess.h>
48 #include <linux/watchdog.h>
50 #include <linux/hiddev.h>
53 #include <linux/sort.h>
55 static int do_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
59 err
= security_file_ioctl(file
, cmd
, arg
);
63 return vfs_ioctl(file
, cmd
, arg
);
67 typedef struct sg_io_hdr32
{
68 compat_int_t interface_id
; /* [i] 'S' for SCSI generic (required) */
69 compat_int_t dxfer_direction
; /* [i] data transfer direction */
70 unsigned char cmd_len
; /* [i] SCSI command length ( <= 16 bytes) */
71 unsigned char mx_sb_len
; /* [i] max length to write to sbp */
72 unsigned short iovec_count
; /* [i] 0 implies no scatter gather */
73 compat_uint_t dxfer_len
; /* [i] byte count of data transfer */
74 compat_uint_t dxferp
; /* [i], [*io] points to data transfer memory
75 or scatter gather list */
76 compat_uptr_t cmdp
; /* [i], [*i] points to command to perform */
77 compat_uptr_t sbp
; /* [i], [*o] points to sense_buffer memory */
78 compat_uint_t timeout
; /* [i] MAX_UINT->no timeout (unit: millisec) */
79 compat_uint_t flags
; /* [i] 0 -> default, see SG_FLAG... */
80 compat_int_t pack_id
; /* [i->o] unused internally (normally) */
81 compat_uptr_t usr_ptr
; /* [i->o] unused internally */
82 unsigned char status
; /* [o] scsi status */
83 unsigned char masked_status
; /* [o] shifted, masked scsi status */
84 unsigned char msg_status
; /* [o] messaging level data (optional) */
85 unsigned char sb_len_wr
; /* [o] byte count actually written to sbp */
86 unsigned short host_status
; /* [o] errors from host adapter */
87 unsigned short driver_status
; /* [o] errors from software driver */
88 compat_int_t resid
; /* [o] dxfer_len - actual_transferred */
89 compat_uint_t duration
; /* [o] time taken by cmd (unit: millisec) */
90 compat_uint_t info
; /* [o] auxiliary information */
91 } sg_io_hdr32_t
; /* 64 bytes long (on sparc32) */
93 typedef struct sg_iovec32
{
94 compat_uint_t iov_base
;
95 compat_uint_t iov_len
;
98 static int sg_build_iovec(sg_io_hdr_t __user
*sgio
, void __user
*dxferp
, u16 iovec_count
)
100 sg_iovec_t __user
*iov
= (sg_iovec_t __user
*) (sgio
+ 1);
101 sg_iovec32_t __user
*iov32
= dxferp
;
104 for (i
= 0; i
< iovec_count
; i
++) {
107 if (get_user(base
, &iov32
[i
].iov_base
) ||
108 get_user(len
, &iov32
[i
].iov_len
) ||
109 put_user(compat_ptr(base
), &iov
[i
].iov_base
) ||
110 put_user(len
, &iov
[i
].iov_len
))
114 if (put_user(iov
, &sgio
->dxferp
))
119 static int sg_ioctl_trans(struct file
*file
, unsigned int cmd
,
120 sg_io_hdr32_t __user
*sgio32
)
122 sg_io_hdr_t __user
*sgio
;
129 if (get_user(interface_id
, &sgio32
->interface_id
))
131 if (interface_id
!= 'S')
132 return do_ioctl(file
, cmd
, (unsigned long)sgio32
);
134 if (get_user(iovec_count
, &sgio32
->iovec_count
))
138 void __user
*top
= compat_alloc_user_space(0);
139 void __user
*new = compat_alloc_user_space(sizeof(sg_io_hdr_t
) +
140 (iovec_count
* sizeof(sg_iovec_t
)));
147 /* Ok, now construct. */
148 if (copy_in_user(&sgio
->interface_id
, &sgio32
->interface_id
,
150 (2 * sizeof(unsigned char)) +
151 (1 * sizeof(unsigned short)) +
152 (1 * sizeof(unsigned int))))
155 if (get_user(data
, &sgio32
->dxferp
))
157 dxferp
= compat_ptr(data
);
159 if (sg_build_iovec(sgio
, dxferp
, iovec_count
))
162 if (put_user(dxferp
, &sgio
->dxferp
))
167 unsigned char __user
*cmdp
;
168 unsigned char __user
*sbp
;
170 if (get_user(data
, &sgio32
->cmdp
))
172 cmdp
= compat_ptr(data
);
174 if (get_user(data
, &sgio32
->sbp
))
176 sbp
= compat_ptr(data
);
178 if (put_user(cmdp
, &sgio
->cmdp
) ||
179 put_user(sbp
, &sgio
->sbp
))
183 if (copy_in_user(&sgio
->timeout
, &sgio32
->timeout
,
187 if (get_user(data
, &sgio32
->usr_ptr
))
189 if (put_user(compat_ptr(data
), &sgio
->usr_ptr
))
192 err
= do_ioctl(file
, cmd
, (unsigned long) sgio
);
197 if (copy_in_user(&sgio32
->pack_id
, &sgio
->pack_id
,
199 get_user(datap
, &sgio
->usr_ptr
) ||
200 put_user((u32
)(unsigned long)datap
,
202 copy_in_user(&sgio32
->status
, &sgio
->status
,
203 (4 * sizeof(unsigned char)) +
204 (2 * sizeof(unsigned short)) +
212 struct compat_sg_req_info
{ /* used by SG_GET_REQUEST_TABLE ioctl() */
218 compat_uptr_t usr_ptr
;
219 unsigned int duration
;
223 static int sg_grt_trans(struct file
*file
,
224 unsigned int cmd
, struct compat_sg_req_info __user
*o
)
227 sg_req_info_t __user
*r
;
228 r
= compat_alloc_user_space(sizeof(sg_req_info_t
)*SG_MAX_QUEUE
);
229 err
= do_ioctl(file
, cmd
, (unsigned long)r
);
232 for (i
= 0; i
< SG_MAX_QUEUE
; i
++) {
236 if (copy_in_user(o
+ i
, r
+ i
, offsetof(sg_req_info_t
, usr_ptr
)) ||
237 get_user(ptr
, &r
[i
].usr_ptr
) ||
238 get_user(d
, &r
[i
].duration
) ||
239 put_user((u32
)(unsigned long)(ptr
), &o
[i
].usr_ptr
) ||
240 put_user(d
, &o
[i
].duration
))
245 #endif /* CONFIG_BLOCK */
247 struct sock_fprog32
{
249 compat_caddr_t filter
;
252 #define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
253 #define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
255 static int ppp_sock_fprog_ioctl_trans(struct file
*file
,
256 unsigned int cmd
, struct sock_fprog32 __user
*u_fprog32
)
258 struct sock_fprog __user
*u_fprog64
= compat_alloc_user_space(sizeof(struct sock_fprog
));
263 if (get_user(flen
, &u_fprog32
->len
) ||
264 get_user(fptr32
, &u_fprog32
->filter
))
267 fptr64
= compat_ptr(fptr32
);
269 if (put_user(flen
, &u_fprog64
->len
) ||
270 put_user(fptr64
, &u_fprog64
->filter
))
273 if (cmd
== PPPIOCSPASS32
)
278 return do_ioctl(file
, cmd
, (unsigned long) u_fprog64
);
281 struct ppp_option_data32
{
284 compat_int_t transmit
;
286 #define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
289 compat_time_t xmit_idle
;
290 compat_time_t recv_idle
;
292 #define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
294 static int ppp_gidle(struct file
*file
, unsigned int cmd
,
295 struct ppp_idle32 __user
*idle32
)
297 struct ppp_idle __user
*idle
;
298 __kernel_time_t xmit
, recv
;
301 idle
= compat_alloc_user_space(sizeof(*idle
));
303 err
= do_ioctl(file
, PPPIOCGIDLE
, (unsigned long) idle
);
306 if (get_user(xmit
, &idle
->xmit_idle
) ||
307 get_user(recv
, &idle
->recv_idle
) ||
308 put_user(xmit
, &idle32
->xmit_idle
) ||
309 put_user(recv
, &idle32
->recv_idle
))
315 static int ppp_scompress(struct file
*file
, unsigned int cmd
,
316 struct ppp_option_data32 __user
*odata32
)
318 struct ppp_option_data __user
*odata
;
322 odata
= compat_alloc_user_space(sizeof(*odata
));
324 if (get_user(data
, &odata32
->ptr
))
327 datap
= compat_ptr(data
);
328 if (put_user(datap
, &odata
->ptr
))
331 if (copy_in_user(&odata
->length
, &odata32
->length
,
332 sizeof(__u32
) + sizeof(int)))
335 return do_ioctl(file
, PPPIOCSCOMPRESS
, (unsigned long) odata
);
339 * simple reversible transform to make our table more evenly
340 * distributed after sorting.
342 #define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff)
344 #define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd),
345 static unsigned int ioctl_pointer
[] = {
347 COMPATIBLE_IOCTL(TIOCOUTQ
)
350 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN
)
351 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK
)
352 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK
)
353 COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY
)
354 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER
)
355 COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND
)
356 COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST
)
357 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI
)
361 COMPATIBLE_IOCTL(SG_SET_TIMEOUT
)
362 COMPATIBLE_IOCTL(SG_GET_TIMEOUT
)
363 COMPATIBLE_IOCTL(SG_EMULATED_HOST
)
364 COMPATIBLE_IOCTL(SG_GET_TRANSFORM
)
365 COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE
)
366 COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE
)
367 COMPATIBLE_IOCTL(SG_GET_SCSI_ID
)
368 COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA
)
369 COMPATIBLE_IOCTL(SG_GET_LOW_DMA
)
370 COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID
)
371 COMPATIBLE_IOCTL(SG_GET_PACK_ID
)
372 COMPATIBLE_IOCTL(SG_GET_NUM_WAITING
)
373 COMPATIBLE_IOCTL(SG_SET_DEBUG
)
374 COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE
)
375 COMPATIBLE_IOCTL(SG_GET_COMMAND_Q
)
376 COMPATIBLE_IOCTL(SG_SET_COMMAND_Q
)
377 COMPATIBLE_IOCTL(SG_GET_VERSION_NUM
)
378 COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN
)
379 COMPATIBLE_IOCTL(SG_SCSI_RESET
)
380 COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE
)
381 COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN
)
382 COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN
)
385 COMPATIBLE_IOCTL(PPPIOCGFLAGS
)
386 COMPATIBLE_IOCTL(PPPIOCSFLAGS
)
387 COMPATIBLE_IOCTL(PPPIOCGASYNCMAP
)
388 COMPATIBLE_IOCTL(PPPIOCSASYNCMAP
)
389 COMPATIBLE_IOCTL(PPPIOCGUNIT
)
390 COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP
)
391 COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP
)
392 COMPATIBLE_IOCTL(PPPIOCGMRU
)
393 COMPATIBLE_IOCTL(PPPIOCSMRU
)
394 COMPATIBLE_IOCTL(PPPIOCSMAXCID
)
395 COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP
)
396 COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP
)
397 COMPATIBLE_IOCTL(PPPIOCXFERUNIT
)
398 /* PPPIOCSCOMPRESS is translated */
399 COMPATIBLE_IOCTL(PPPIOCGNPMODE
)
400 COMPATIBLE_IOCTL(PPPIOCSNPMODE
)
401 COMPATIBLE_IOCTL(PPPIOCGDEBUG
)
402 COMPATIBLE_IOCTL(PPPIOCSDEBUG
)
403 /* PPPIOCSPASS is translated */
404 /* PPPIOCSACTIVE is translated */
405 /* PPPIOCGIDLE is translated */
406 COMPATIBLE_IOCTL(PPPIOCNEWUNIT
)
407 COMPATIBLE_IOCTL(PPPIOCATTACH
)
408 COMPATIBLE_IOCTL(PPPIOCDETACH
)
409 COMPATIBLE_IOCTL(PPPIOCSMRRU
)
410 COMPATIBLE_IOCTL(PPPIOCCONNECT
)
411 COMPATIBLE_IOCTL(PPPIOCDISCONN
)
412 COMPATIBLE_IOCTL(PPPIOCATTCHAN
)
413 COMPATIBLE_IOCTL(PPPIOCGCHAN
)
414 COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS
)
416 COMPATIBLE_IOCTL(WDIOC_GETSUPPORT
)
417 COMPATIBLE_IOCTL(WDIOC_GETSTATUS
)
418 COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS
)
419 COMPATIBLE_IOCTL(WDIOC_GETTEMP
)
420 COMPATIBLE_IOCTL(WDIOC_SETOPTIONS
)
421 COMPATIBLE_IOCTL(WDIOC_KEEPALIVE
)
422 COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT
)
423 COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT
)
424 COMPATIBLE_IOCTL(WDIOC_SETPRETIMEOUT
)
425 COMPATIBLE_IOCTL(WDIOC_GETPRETIMEOUT
)
429 * Convert common ioctl arguments based on their command number
431 * Please do not add any code in here. Instead, implement
432 * a compat_ioctl operation in the place that handleѕ the
433 * ioctl for the native case.
435 static long do_ioctl_trans(unsigned int cmd
,
436 unsigned long arg
, struct file
*file
)
438 void __user
*argp
= compat_ptr(arg
);
442 return ppp_gidle(file
, cmd
, argp
);
443 case PPPIOCSCOMPRESS32
:
444 return ppp_scompress(file
, cmd
, argp
);
446 case PPPIOCSACTIVE32
:
447 return ppp_sock_fprog_ioctl_trans(file
, cmd
, argp
);
450 return sg_ioctl_trans(file
, cmd
, argp
);
451 case SG_GET_REQUEST_TABLE
:
452 return sg_grt_trans(file
, cmd
, argp
);
459 static int compat_ioctl_check_table(unsigned int xcmd
)
462 const int max
= ARRAY_SIZE(ioctl_pointer
) - 1;
464 BUILD_BUG_ON(max
>= (1 << 16));
466 /* guess initial offset into table, assuming a
467 normalized distribution */
468 i
= ((xcmd
>> 16) * max
) >> 16;
470 /* do linear search up first, until greater or equal */
471 while (ioctl_pointer
[i
] < xcmd
&& i
< max
)
474 /* then do linear search down */
475 while (ioctl_pointer
[i
] > xcmd
&& i
> 0)
478 return ioctl_pointer
[i
] == xcmd
;
481 COMPAT_SYSCALL_DEFINE3(ioctl
, unsigned int, fd
, unsigned int, cmd
,
482 compat_ulong_t
, arg32
)
484 unsigned long arg
= arg32
;
485 struct fd f
= fdget(fd
);
490 /* RED-PEN how should LSM module know it's handling 32bit? */
491 error
= security_file_ioctl(f
.file
, cmd
, arg
);
496 /* these are never seen by ->ioctl(), no argument or int argument */
503 /* these are never seen by ->ioctl(), pointer argument */
513 * The next group is the stuff handled inside file_ioctl().
514 * For regular files these never reach ->ioctl(); for
515 * devices, sockets, etc. they do and one (FIONREAD) is
516 * even accepted in some cases. In all those cases
517 * argument has the same type, so we can handle these
518 * here, shunting them towards do_vfs_ioctl().
519 * ->compat_ioctl() will never see any of those.
521 /* pointer argument, never actually handled by ->ioctl() */
524 /* handled by some ->ioctl(); always a pointer to int */
527 /* these two get messy on amd64 due to alignment differences */
528 #if defined(CONFIG_X86_64)
529 case FS_IOC_RESVSP_32
:
530 case FS_IOC_RESVSP64_32
:
531 error
= compat_ioctl_preallocate(f
.file
, compat_ptr(arg
));
535 case FS_IOC_RESVSP64
:
540 if (f
.file
->f_op
->compat_ioctl
) {
541 error
= f
.file
->f_op
->compat_ioctl(f
.file
, cmd
, arg
);
542 if (error
!= -ENOIOCTLCMD
)
546 if (!f
.file
->f_op
->unlocked_ioctl
)
551 if (compat_ioctl_check_table(XFORM(cmd
)))
554 error
= do_ioctl_trans(cmd
, arg
, f
.file
);
555 if (error
== -ENOIOCTLCMD
)
561 arg
= (unsigned long)compat_ptr(arg
);
563 error
= do_vfs_ioctl(f
.file
, fd
, cmd
, arg
);
570 static int __init
init_sys32_ioctl_cmp(const void *p
, const void *q
)
573 a
= *(unsigned int *)p
;
574 b
= *(unsigned int *)q
;
582 static int __init
init_sys32_ioctl(void)
584 sort(ioctl_pointer
, ARRAY_SIZE(ioctl_pointer
), sizeof(*ioctl_pointer
),
585 init_sys32_ioctl_cmp
, NULL
);
588 __initcall(init_sys32_ioctl
);