2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-2001 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999-2019 The strace developers.
9 * SPDX-License-Identifier: LGPL-2.1-or-later
13 #include <linux/ioctl.h>
14 #include "xlat/ioctl_dirs.h"
17 compare(const void *a, const void *b)
19 const unsigned int code1 = (const uintptr_t) a;
20 const unsigned int code2 = ((struct_ioctlent *) b)->code;
21 return (code1 > code2) ? 1 : (code1 < code2) ? -1 : 0;
24 static const struct_ioctlent *
25 ioctl_lookup(const unsigned int code)
29 iop = bsearch((const void *) (const uintptr_t) code, ioctlent,
30 nioctlents, sizeof(ioctlent[0]), compare);
31 while (iop > ioctlent) {
33 if (iop->code != code) {
41 static const struct_ioctlent *
42 ioctl_next_match(const struct_ioctlent *iop)
44 const unsigned int code = iop->code;
46 if (iop < ioctlent + nioctlents && iop->code == code)
52 ioctl_print_code(const unsigned int code)
54 const bool abbrev = xlat_verbose(xlat_verbosity) != XLAT_STYLE_VERBOSE;
57 printflags_ex(_IOC_DIR(code), abbrev ? "_IOC_???" : NULL,
58 abbrev ? XLAT_STYLE_DEFAULT : XLAT_STYLE_ABBREV,
60 tprintf(", %#x, %#x, %#x)",
61 _IOC_TYPE(code), _IOC_NR(code), _IOC_SIZE(code));
65 evdev_decode_number(const unsigned int code)
67 const unsigned int nr = _IOC_NR(code);
68 const bool abbrev = xlat_verbose(xlat_verbosity) != XLAT_STYLE_VERBOSE;
70 if (_IOC_DIR(code) == _IOC_WRITE) {
71 if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
72 tprints("EVIOCSABS(");
73 printxval_ex(evdev_abs, nr - 0xc0,
74 abbrev ? "ABS_???" : NULL,
75 abbrev ? XLAT_STYLE_DEFAULT
82 if (_IOC_DIR(code) != _IOC_READ)
85 if (nr >= 0x20 && nr <= 0x20 + 0x1f) {
86 tprints("EVIOCGBIT(");
90 printxval_ex(evdev_ev, nr - 0x20,
91 abbrev ? "EV_???" : NULL,
92 abbrev ? XLAT_STYLE_DEFAULT
94 tprintf(", %u)", _IOC_SIZE(code));
96 } else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
97 tprints("EVIOCGABS(");
98 printxval_ex(evdev_abs, nr - 0x40, abbrev ? "ABS_???" : NULL,
99 abbrev ? XLAT_STYLE_DEFAULT : XLAT_STYLE_ABBREV);
106 tprintf("EVIOCGNAME(%u)", _IOC_SIZE(code));
109 tprintf("EVIOCGPHYS(%u)", _IOC_SIZE(code));
112 tprintf("EVIOCGUNIQ(%u)", _IOC_SIZE(code));
115 tprintf("EVIOCGPROP(%u)", _IOC_SIZE(code));
118 tprintf("EVIOCGMTSLOTS(%u)", _IOC_SIZE(code));
121 tprintf("EVIOCGKEY(%u)", _IOC_SIZE(code));
124 tprintf("EVIOCGLED(%u)", _IOC_SIZE(code));
127 tprintf("EVIOCGSND(%u)", _IOC_SIZE(code));
130 tprintf("EVIOCGSW(%u)", _IOC_SIZE(code));
138 hiddev_decode_number(const unsigned int code)
140 if (_IOC_DIR(code) == _IOC_READ) {
141 switch (_IOC_NR(code)) {
143 tprintf("HIDIOCGRAWNAME(%u)", _IOC_SIZE(code));
146 tprintf("HIDIOCGRAWPHYS(%u)", _IOC_SIZE(code));
149 tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
152 tprintf("HIDIOCGPHYS(%u)", _IOC_SIZE(code));
157 } else if (_IOC_DIR(code) == (_IOC_READ | _IOC_WRITE)) {
158 switch (_IOC_NR(code)) {
160 tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
163 tprintf("HIDIOCGFEATURE(%u)", _IOC_SIZE(code));
174 ioctl_decode_command_number(struct tcb *tcp)
176 const unsigned int code = tcp->u_arg[1];
178 switch (_IOC_TYPE(code)) {
180 return evdev_decode_number(code);
182 return hiddev_decode_number(code);
184 if (_IOC_DIR(code) == _IOC_WRITE) {
185 tprintf("MIXER_WRITE(%u)", _IOC_NR(code));
187 } else if (_IOC_DIR(code) == _IOC_READ) {
188 tprintf("MIXER_READ(%u)", _IOC_NR(code));
193 if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x2c) {
194 tprintf("UI_GET_SYSNAME(%u)", _IOC_SIZE(code));
199 if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x13) {
200 tprintf("JSIOCGNAME(%u)", _IOC_SIZE(code));
205 if (_IOC_DIR(code) == _IOC_WRITE && _IOC_NR(code) == 0) {
206 tprintf("SPI_IOC_MESSAGE(%u)", _IOC_SIZE(code));
216 * Decode arg parameter of the ioctl call.
218 * @return There are two flags of the return value important for the purposes of
219 * processing by SYS_FUNC(ioctl):
220 * - RVAL_IOCTL_DECODED: indicates that ioctl decoder code
221 * has printed arg parameter;
222 * - RVAL_DECODED: indicates that decoding is done.
223 * As a result, the following behaviour is expected:
225 * - 0: decoding should be continued on exiting;
226 * - RVAL_IOCTL_DECODED: decoding on exiting is not needed
227 * and decoder has printed arg value;
228 * - RVAL_DECODED: decoding on exiting is not needed
229 * and generic handler should print arg value.
231 * - 0: generic handler should print arg value;
232 * - RVAL_IOCTL_DECODED: decoder has printed arg value.
234 * Note that it makes no sense to return just RVAL_DECODED on exiting,
235 * but, of course, it is not prohibited (for example, it may be useful
236 * in cases where the return path is common on entering and on exiting
239 * SYS_FUNC(ioctl) converts RVAL_IOCTL_DECODED flag to RVAL_DECODED,
240 * and passes all other bits of ioctl_decode return value unchanged.
243 ioctl_decode(struct tcb *tcp)
245 const unsigned int code = tcp->u_arg[1];
246 const kernel_ulong_t arg = tcp->u_arg[2];
248 switch (_IOC_TYPE(code)) {
250 return hdio_ioctl(tcp, code, arg);
252 return block_ioctl(tcp, code, arg);
254 return scsi_ioctl(tcp, code, arg);
256 return perf_ioctl(tcp, code, arg);
257 #ifdef HAVE_STRUCT_PTP_SYS_OFFSET
259 return ptp_ioctl(tcp, code, arg);
261 #ifdef HAVE_LINUX_INPUT_H
263 return evdev_ioctl(tcp, code, arg);
266 return inotify_ioctl(tcp, code, arg);
268 return loop_ioctl(tcp, code, arg);
269 #ifdef HAVE_STRUCT_MTD_WRITE_REQ
271 return mtd_ioctl(tcp, code, arg);
273 #ifdef HAVE_STRUCT_UBI_ATTACH_REQ_MAX_BEB_PER1024
275 return ubi_ioctl(tcp, code, arg);
278 return random_ioctl(tcp, code, arg);
280 return term_ioctl(tcp, code, arg);
282 return v4l2_ioctl(tcp, code, arg);
284 return watchdog_ioctl(tcp, code, arg);
286 return fs_x_ioctl(tcp, code, arg);
288 #if defined(ALPHA) || defined(POWERPC)
289 int ret = file_ioctl(tcp, code, arg);
290 if (ret != RVAL_DECODED)
292 return term_ioctl(tcp, code, arg);
293 #else /* !(ALPHA || POWERPC) */
294 return file_ioctl(tcp, code, arg);
295 #endif /* (ALPHA || POWERPC) */
297 #ifdef HAVE_STRUCT_UBI_ATTACH_REQ_MAX_BEB_PER1024
299 return ubi_ioctl(tcp, code, arg);
302 return rtc_ioctl(tcp, code, arg);
303 #if defined(ALPHA) || defined(POWERPC)
305 return term_ioctl(tcp, code, arg);
308 return sock_ioctl(tcp, code, arg);
309 #ifdef HAVE_LINUX_BTRFS_H
311 return btrfs_ioctl(tcp, code, arg);
313 #ifdef HAVE_LINUX_USERFAULTFD_H
315 return uffdio_ioctl(tcp, code, arg);
318 return nbd_ioctl(tcp, code, arg);
319 #ifdef HAVE_LINUX_KVM_H
321 return kvm_ioctl(tcp, code, arg);
324 return nsfs_ioctl(tcp, code, arg);
325 #ifdef HAVE_LINUX_DM_IOCTL_H
327 return dm_ioctl(tcp, code, arg);
337 const struct_ioctlent *iop;
341 printfd(tcp, tcp->u_arg[0]);
344 if (xlat_verbosity != XLAT_STYLE_ABBREV)
345 tprintf("%#x", (unsigned int) tcp->u_arg[1]);
346 if (xlat_verbosity == XLAT_STYLE_VERBOSE)
348 if (xlat_verbosity != XLAT_STYLE_RAW) {
349 ret = ioctl_decode_command_number(tcp);
350 if (!(ret & IOCTL_NUMBER_STOP_LOOKUP)) {
351 iop = ioctl_lookup(tcp->u_arg[1]);
355 tprints(iop->symbol);
356 while ((iop = ioctl_next_match(iop)))
357 tprintf(" or %s", iop->symbol);
359 ioctl_print_code(tcp->u_arg[1]);
363 if (xlat_verbosity == XLAT_STYLE_VERBOSE)
366 ret = ioctl_decode(tcp);
368 ret = ioctl_decode(tcp) | RVAL_DECODED;
371 if (ret & RVAL_IOCTL_DECODED) {
372 ret &= ~RVAL_IOCTL_DECODED;
374 } else if (ret & RVAL_DECODED) {
375 tprintf(", %#" PRI_klx, tcp->u_arg[2]);