Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl>
      3  * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl>
      4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com>
      5  * Copyright (c) 1996-2001 Wichert Akkerman <wichert (at) cistron.nl>
      6  * Copyright (c) 1999-2017 The strace developers.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. The name of the author may not be used to endorse or promote products
     18  *    derived from this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include "defs.h"
     33 #include <linux/ioctl.h>
     34 #include "xlat/ioctl_dirs.h"
     35 
     36 #ifdef HAVE_LINUX_INPUT_H
     37 # include <linux/input.h>
     38 #endif
     39 
     40 #include "xlat/evdev_abs.h"
     41 #include "xlat/evdev_ev.h"
     42 
     43 static int
     44 compare(const void *a, const void *b)
     45 {
     46 	const unsigned int code1 = (const uintptr_t) a;
     47 	const unsigned int code2 = ((struct_ioctlent *) b)->code;
     48 	return (code1 > code2) ? 1 : (code1 < code2) ? -1 : 0;
     49 }
     50 
     51 static const struct_ioctlent *
     52 ioctl_lookup(const unsigned int code)
     53 {
     54 	struct_ioctlent *iop;
     55 
     56 	iop = bsearch((const void *) (const uintptr_t) code, ioctlent,
     57 			nioctlents, sizeof(ioctlent[0]), compare);
     58 	while (iop > ioctlent) {
     59 		iop--;
     60 		if (iop->code != code) {
     61 			iop++;
     62 			break;
     63 		}
     64 	}
     65 	return iop;
     66 }
     67 
     68 static const struct_ioctlent *
     69 ioctl_next_match(const struct_ioctlent *iop)
     70 {
     71 	const unsigned int code = iop->code;
     72 	iop++;
     73 	if (iop < ioctlent + nioctlents && iop->code == code)
     74 		return iop;
     75 	return NULL;
     76 }
     77 
     78 static void
     79 ioctl_print_code(const unsigned int code)
     80 {
     81 	tprints("_IOC(");
     82 	printflags(ioctl_dirs, _IOC_DIR(code), "_IOC_???");
     83 	tprintf(", %#x, %#x, %#x)",
     84 		_IOC_TYPE(code), _IOC_NR(code), _IOC_SIZE(code));
     85 }
     86 
     87 static int
     88 evdev_decode_number(const unsigned int code)
     89 {
     90 	const unsigned int nr = _IOC_NR(code);
     91 
     92 	if (_IOC_DIR(code) == _IOC_WRITE) {
     93 		if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
     94 			tprints("EVIOCSABS(");
     95 			printxval(evdev_abs, nr - 0xc0, "ABS_???");
     96 			tprints(")");
     97 			return 1;
     98 		}
     99 	}
    100 
    101 	if (_IOC_DIR(code) != _IOC_READ)
    102 		return 0;
    103 
    104 	if (nr >= 0x20 && nr <= 0x20 + 0x1f) {
    105 		tprints("EVIOCGBIT(");
    106 		printxval(evdev_ev, nr - 0x20, "EV_???");
    107 		tprintf(", %u)", _IOC_SIZE(code));
    108 		return 1;
    109 	} else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
    110 		tprints("EVIOCGABS(");
    111 		printxval(evdev_abs, nr - 0x40, "ABS_???");
    112 		tprints(")");
    113 		return 1;
    114 	}
    115 
    116 	switch (_IOC_NR(nr)) {
    117 		case 0x06:
    118 			tprintf("EVIOCGNAME(%u)", _IOC_SIZE(code));
    119 			return 1;
    120 		case 0x07:
    121 			tprintf("EVIOCGPHYS(%u)", _IOC_SIZE(code));
    122 			return 1;
    123 		case 0x08:
    124 			tprintf("EVIOCGUNIQ(%u)", _IOC_SIZE(code));
    125 			return 1;
    126 		case 0x09:
    127 			tprintf("EVIOCGPROP(%u)", _IOC_SIZE(code));
    128 			return 1;
    129 		case 0x0a:
    130 			tprintf("EVIOCGMTSLOTS(%u)", _IOC_SIZE(code));
    131 			return 1;
    132 		case 0x18:
    133 			tprintf("EVIOCGKEY(%u)", _IOC_SIZE(code));
    134 			return 1;
    135 		case 0x19:
    136 			tprintf("EVIOCGLED(%u)", _IOC_SIZE(code));
    137 			return 1;
    138 		case 0x1a:
    139 			tprintf("EVIOCGSND(%u)", _IOC_SIZE(code));
    140 			return 1;
    141 		case 0x1b:
    142 			tprintf("EVIOCGSW(%u)", _IOC_SIZE(code));
    143 			return 1;
    144 		default:
    145 			return 0;
    146 	}
    147 }
    148 
    149 static int
    150 hiddev_decode_number(const unsigned int code)
    151 {
    152 	if (_IOC_DIR(code) == _IOC_READ) {
    153 		switch (_IOC_NR(code)) {
    154 			case 0x04:
    155 				tprintf("HIDIOCGRAWNAME(%u)", _IOC_SIZE(code));
    156 				return 1;
    157 			case 0x05:
    158 				tprintf("HIDIOCGRAWPHYS(%u)", _IOC_SIZE(code));
    159 				return 1;
    160 			case 0x06:
    161 				tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
    162 				return 1;
    163 			case 0x12:
    164 				tprintf("HIDIOCGPHYS(%u)", _IOC_SIZE(code));
    165 				return 1;
    166 			default:
    167 				return 0;
    168 		}
    169 	} else if (_IOC_DIR(code) == (_IOC_READ | _IOC_WRITE)) {
    170 		switch (_IOC_NR(code)) {
    171 			case 0x06:
    172 				tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
    173 				return 1;
    174 			case 0x07:
    175 				tprintf("HIDIOCGFEATURE(%u)", _IOC_SIZE(code));
    176 				return 1;
    177 			default:
    178 				return 0;
    179 		}
    180 	}
    181 
    182 	return 0;
    183 }
    184 
    185 static int
    186 ioctl_decode_command_number(struct tcb *tcp)
    187 {
    188 	const unsigned int code = tcp->u_arg[1];
    189 
    190 	switch (_IOC_TYPE(code)) {
    191 		case 'E':
    192 			return evdev_decode_number(code);
    193 		case 'H':
    194 			return hiddev_decode_number(code);
    195 		case 'M':
    196 			if (_IOC_DIR(code) == _IOC_WRITE) {
    197 				tprintf("MIXER_WRITE(%u)", _IOC_NR(code));
    198 				return 1;
    199 			} else if (_IOC_DIR(code) == _IOC_READ) {
    200 				tprintf("MIXER_READ(%u)", _IOC_NR(code));
    201 				return 1;
    202 			}
    203 			return 0;
    204 		case 'U':
    205 			if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x2c) {
    206 				tprintf("UI_GET_SYSNAME(%u)", _IOC_SIZE(code));
    207 				return 1;
    208 			}
    209 			return 0;
    210 		case 'j':
    211 			if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x13) {
    212 				tprintf("JSIOCGNAME(%u)", _IOC_SIZE(code));
    213 				return 1;
    214 			}
    215 			return 0;
    216 		case 'k':
    217 			if (_IOC_DIR(code) == _IOC_WRITE && _IOC_NR(code) == 0) {
    218 				tprintf("SPI_IOC_MESSAGE(%u)", _IOC_SIZE(code));
    219 				return 1;
    220 			}
    221 			return 0;
    222 		default:
    223 			return 0;
    224 	}
    225 }
    226 
    227 /**
    228  * Decode arg parameter of the ioctl call.
    229  *
    230  * @return There are two flags of the return value important for the purposes of
    231  *         processing by SYS_FUNC(ioctl):
    232  *          - RVAL_IOCTL_DECODED: indicates that ioctl decoder code
    233  *                                has printed arg parameter;
    234  *          - RVAL_DECODED: indicates that decoding is done.
    235  *         As a result, the following behaviour is expected:
    236  *          - on entering:
    237  *            - 0: decoding should be continued on exiting;
    238  *            - RVAL_IOCTL_DECODED: decoding on exiting is not needed
    239  *                                  and decoder has printed arg value;
    240  *            - RVAL_DECODED: decoding on exiting is not needed
    241  *                            and generic handler should print arg value.
    242  *          - on exiting:
    243  *            - 0: generic handler should print arg value;
    244  *            - RVAL_IOCTL_DECODED: decoder has printed arg value.
    245  *
    246  *         Note that it makes no sense to return just RVAL_DECODED on exiting,
    247  *         but, of course, it is not prohibited (for example, it may be useful
    248  *         in cases where the return path is common on entering and on exiting
    249  *         the syscall).
    250  *
    251  *         SYS_FUNC(ioctl) converts RVAL_IOCTL_DECODED flag to RVAL_DECODED,
    252  *         and passes all other bits of ioctl_decode return value unchanged.
    253  */
    254 static int
    255 ioctl_decode(struct tcb *tcp)
    256 {
    257 	const unsigned int code = tcp->u_arg[1];
    258 	const kernel_ulong_t arg = tcp->u_arg[2];
    259 
    260 	switch (_IOC_TYPE(code)) {
    261 #if defined(ALPHA) || defined(POWERPC)
    262 	case 'f': {
    263 		int ret = file_ioctl(tcp, code, arg);
    264 		if (ret != RVAL_DECODED)
    265 			return ret;
    266 	}
    267 	case 't':
    268 	case 'T':
    269 		return term_ioctl(tcp, code, arg);
    270 #else /* !ALPHA */
    271 	case 'f':
    272 		return file_ioctl(tcp, code, arg);
    273 	case 0x54:
    274 #endif /* !ALPHA */
    275 		return term_ioctl(tcp, code, arg);
    276 	case 0x89:
    277 		return sock_ioctl(tcp, code, arg);
    278 	case 'p':
    279 		return rtc_ioctl(tcp, code, arg);
    280 	case 0x03:
    281 		return hdio_ioctl(tcp, code, arg);
    282 	case 0x12:
    283 		return block_ioctl(tcp, code, arg);
    284 	case 'X':
    285 		return fs_x_ioctl(tcp, code, arg);
    286 	case 0x22:
    287 		return scsi_ioctl(tcp, code, arg);
    288 	case 'L':
    289 		return loop_ioctl(tcp, code, arg);
    290 #ifdef HAVE_STRUCT_MTD_WRITE_REQ
    291 	case 'M':
    292 		return mtd_ioctl(tcp, code, arg);
    293 #endif
    294 #ifdef HAVE_STRUCT_UBI_ATTACH_REQ_MAX_BEB_PER1024
    295 	case 'o':
    296 	case 'O':
    297 		return ubi_ioctl(tcp, code, arg);
    298 #endif
    299 	case 'V':
    300 		return v4l2_ioctl(tcp, code, arg);
    301 #ifdef HAVE_STRUCT_PTP_SYS_OFFSET
    302 	case '=':
    303 		return ptp_ioctl(tcp, code, arg);
    304 #endif
    305 #ifdef HAVE_LINUX_INPUT_H
    306 	case 'E':
    307 		return evdev_ioctl(tcp, code, arg);
    308 #endif
    309 #ifdef HAVE_LINUX_USERFAULTFD_H
    310 	case 0xaa:
    311 		return uffdio_ioctl(tcp, code, arg);
    312 #endif
    313 #ifdef HAVE_LINUX_BTRFS_H
    314 	case 0x94:
    315 		return btrfs_ioctl(tcp, code, arg);
    316 #endif
    317 	case 0xb7:
    318 		return nsfs_ioctl(tcp, code, arg);
    319 #ifdef HAVE_LINUX_DM_IOCTL_H
    320 	case 0xfd:
    321 		return dm_ioctl(tcp, code, arg);
    322 #endif
    323 #ifdef HAVE_LINUX_KVM_H
    324 	case 0xae:
    325 		return kvm_ioctl(tcp, code, arg);
    326 #endif
    327 	default:
    328 		break;
    329 	}
    330 	return 0;
    331 }
    332 
    333 SYS_FUNC(ioctl)
    334 {
    335 	const struct_ioctlent *iop;
    336 	int ret;
    337 
    338 	if (entering(tcp)) {
    339 		printfd(tcp, tcp->u_arg[0]);
    340 		tprints(", ");
    341 		ret = ioctl_decode_command_number(tcp);
    342 		if (!(ret & IOCTL_NUMBER_STOP_LOOKUP)) {
    343 			iop = ioctl_lookup(tcp->u_arg[1]);
    344 			if (iop) {
    345 				if (ret)
    346 					tprints(" or ");
    347 				tprints(iop->symbol);
    348 				while ((iop = ioctl_next_match(iop)))
    349 					tprintf(" or %s", iop->symbol);
    350 			} else if (!ret) {
    351 				ioctl_print_code(tcp->u_arg[1]);
    352 			}
    353 		}
    354 		ret = ioctl_decode(tcp);
    355 	} else {
    356 		ret = ioctl_decode(tcp) | RVAL_DECODED;
    357 	}
    358 
    359 	if (ret & RVAL_IOCTL_DECODED) {
    360 		ret &= ~RVAL_IOCTL_DECODED;
    361 		ret |= RVAL_DECODED;
    362 	} else if (ret & RVAL_DECODED) {
    363 		tprintf(", %#" PRI_klx, tcp->u_arg[2]);
    364 	}
    365 
    366 	return ret;
    367 }
    368