• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015 Etienne Gemsa <etienne.gemsa@lse.epita.fr>
3  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
4  * Copyright (c) 2015-2018 The strace developers.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "defs.h"
31 
32 #include "xlat/evdev_abs.h"
33 #include "xlat/evdev_ev.h"
34 
35 #ifdef HAVE_LINUX_INPUT_H
36 
37 # include <linux/ioctl.h>
38 # include <linux/input.h>
39 
40 # include "xlat/evdev_autorepeat.h"
41 # include "xlat/evdev_ff_status.h"
42 # include "xlat/evdev_ff_types.h"
43 # include "xlat/evdev_keycode.h"
44 # include "xlat/evdev_leds.h"
45 # include "xlat/evdev_misc.h"
46 # include "xlat/evdev_mtslots.h"
47 # include "xlat/evdev_prop.h"
48 # include "xlat/evdev_relative_axes.h"
49 # include "xlat/evdev_snd.h"
50 # include "xlat/evdev_switch.h"
51 
52 # ifndef SYN_MAX
53 #  define SYN_MAX 0xf
54 # endif
55 
56 const size_t evdev_abs_size = ARRAY_SIZE(evdev_abs) - 1;
57 
58 static int
abs_ioctl(struct tcb * const tcp,const kernel_ulong_t arg)59 abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
60 {
61 	tprints(", ");
62 
63 	struct input_absinfo absinfo;
64 
65 	if (!umove_or_printaddr(tcp, arg, &absinfo)) {
66 		tprintf("{value=%u"
67 			", minimum=%u, ",
68 			absinfo.value,
69 			absinfo.minimum);
70 
71 		if (!abbrev(tcp)) {
72 			tprintf("maximum=%u"
73 				", fuzz=%u"
74 				", flat=%u",
75 				absinfo.maximum,
76 				absinfo.fuzz,
77 				absinfo.flat);
78 # ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
79 			tprintf(", resolution=%u",
80 				absinfo.resolution);
81 # endif
82 		} else {
83 			tprints("...");
84 		}
85 
86 		tprints("}");
87 	}
88 
89 	return RVAL_IOCTL_DECODED;
90 }
91 
92 static int
keycode_ioctl(struct tcb * const tcp,const kernel_ulong_t arg)93 keycode_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
94 {
95 	tprints(", ");
96 
97 	unsigned int keycode[2];
98 
99 	if (!umove_or_printaddr(tcp, arg, &keycode)) {
100 		tprintf("[%u, ", keycode[0]);
101 		printxval_index(evdev_keycode, keycode[1], "KEY_???");
102 		tprints("]");
103 	}
104 
105 	return RVAL_IOCTL_DECODED;
106 }
107 
108 # ifdef EVIOCGKEYCODE_V2
109 static int
keycode_V2_ioctl(struct tcb * const tcp,const kernel_ulong_t arg)110 keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
111 {
112 	tprints(", ");
113 
114 	struct input_keymap_entry ike;
115 
116 	if (umove_or_printaddr(tcp, arg, &ike))
117 		return RVAL_IOCTL_DECODED;
118 
119 	tprintf("{flags=%" PRIu8
120 		", len=%" PRIu8 ", ",
121 		ike.flags,
122 		ike.len);
123 
124 	if (!abbrev(tcp)) {
125 		unsigned int i;
126 
127 		tprintf("index=%" PRIu16 ", keycode=", ike.index);
128 		printxval_index(evdev_keycode, ike.keycode, "KEY_???");
129 		tprints(", scancode=[");
130 		for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
131 			if (i > 0)
132 				tprints(", ");
133 			tprintf("%" PRIx8, ike.scancode[i]);
134 		}
135 		tprints("]");
136 	} else {
137 		tprints("...");
138 	}
139 
140 	tprints("}");
141 
142 	return RVAL_IOCTL_DECODED;
143 }
144 # endif /* EVIOCGKEYCODE_V2 */
145 
146 static int
getid_ioctl(struct tcb * const tcp,const kernel_ulong_t arg)147 getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
148 {
149 	tprints(", ");
150 
151 	struct input_id id;
152 
153 	if (!umove_or_printaddr(tcp, arg, &id))
154 		tprintf("{ID_BUS=%" PRIu16
155 			", ID_VENDOR=%" PRIu16
156 			", ID_PRODUCT=%" PRIu16
157 			", ID_VERSION=%" PRIu16 "}",
158 			id.bustype,
159 			id.vendor,
160 			id.product,
161 			id.version);
162 
163 	return RVAL_IOCTL_DECODED;
164 }
165 
166 static int
decode_bitset_(struct tcb * const tcp,const kernel_ulong_t arg,const struct xlat decode_nr[],const unsigned int max_nr,const char * const dflt,size_t decode_nr_size,enum xlat_type xt)167 decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
168 	       const struct xlat decode_nr[], const unsigned int max_nr,
169 	       const char *const dflt, size_t decode_nr_size, enum xlat_type xt)
170 {
171 	tprints(", ");
172 
173 	unsigned int size;
174 	if ((kernel_ulong_t) tcp->u_rval > max_nr / 8)
175 		size = max_nr;
176 	else
177 		size = tcp->u_rval * 8;
178 	char decoded_arg[size];
179 
180 	if (umove_or_printaddr(tcp, arg, &decoded_arg))
181 		return RVAL_IOCTL_DECODED;
182 
183 	tprints("[");
184 
185 	int bit_displayed = 0;
186 	int i = next_set_bit(decoded_arg, 0, size);
187 	if (i < 0) {
188 		tprints(" 0 ");
189 	} else {
190 		printxval_dispatch(decode_nr, decode_nr_size, i, dflt, xt);
191 
192 		while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) {
193 			if (abbrev(tcp) && bit_displayed >= 3) {
194 				tprints(", ...");
195 				break;
196 			}
197 			tprints(", ");
198 			printxval_dispatch(decode_nr, decode_nr_size, i, dflt,
199 					   xt);
200 			bit_displayed++;
201 		}
202 	}
203 
204 	tprints("]");
205 
206 	return RVAL_IOCTL_DECODED;
207 }
208 
209 #define decode_bitset(tcp_, arg_, decode_nr_, max_nr_, dflt_, xt_) \
210 	decode_bitset_((tcp_), (arg_), (decode_nr_), (max_nr_), \
211 		       (dflt_), ARRAY_SIZE(decode_nr_), (xt_))
212 
213 # ifdef EVIOCGMTSLOTS
214 static int
mtslots_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)215 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
216 	      const kernel_ulong_t arg)
217 {
218 	tprints(", ");
219 
220 	const size_t size = _IOC_SIZE(code) / sizeof(int);
221 	if (!size) {
222 		printaddr(arg);
223 		return RVAL_IOCTL_DECODED;
224 	}
225 
226 	int buffer[size];
227 
228 	if (umove_or_printaddr(tcp, arg, &buffer))
229 		return RVAL_IOCTL_DECODED;
230 
231 	tprints("{code=");
232 	printxval(evdev_mtslots, buffer[0], "ABS_MT_???");
233 
234 	tprints(", values=[");
235 
236 	unsigned int i;
237 	for (i = 1; i < ARRAY_SIZE(buffer); i++)
238 		tprintf("%s%d", i > 1 ? ", " : "", buffer[i]);
239 
240 	tprints("]}");
241 
242 	return RVAL_IOCTL_DECODED;
243 }
244 # endif /* EVIOCGMTSLOTS */
245 
246 # if defined EVIOCGREP || defined EVIOCSREP
247 static int
repeat_ioctl(struct tcb * const tcp,const kernel_ulong_t arg)248 repeat_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
249 {
250 	tprints(", ");
251 	printpair_int(tcp, arg, "%u");
252 	return RVAL_IOCTL_DECODED;
253 }
254 # endif /* EVIOCGREP || EVIOCSREP */
255 
256 static int
bit_ioctl(struct tcb * const tcp,const unsigned int ev_nr,const kernel_ulong_t arg)257 bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
258 	  const kernel_ulong_t arg)
259 {
260 	switch (ev_nr) {
261 		case 0:
262 			return decode_bitset(tcp, arg, evdev_ev,
263 					     EV_MAX, "EV_???", XT_SORTED);
264 		case EV_KEY:
265 			return decode_bitset(tcp, arg, evdev_keycode,
266 					     KEY_MAX, "KEY_???", XT_INDEXED);
267 		case EV_REL:
268 			return decode_bitset(tcp, arg, evdev_relative_axes,
269 					     REL_MAX, "REL_???", XT_INDEXED);
270 		case EV_ABS:
271 			return decode_bitset(tcp, arg, evdev_abs,
272 					     ABS_MAX, "ABS_???", XT_INDEXED);
273 		case EV_MSC:
274 			return decode_bitset(tcp, arg, evdev_misc,
275 					     MSC_MAX, "MSC_???", XT_INDEXED);
276 		case EV_SW:
277 			return decode_bitset(tcp, arg, evdev_switch,
278 					     SW_MAX, "SW_???", XT_INDEXED);
279 		case EV_LED:
280 			return decode_bitset(tcp, arg, evdev_leds,
281 					     LED_MAX, "LED_???", XT_INDEXED);
282 		case EV_SND:
283 			return decode_bitset(tcp, arg, evdev_snd,
284 					     SND_MAX, "SND_???", XT_INDEXED);
285 		case EV_REP:
286 			return decode_bitset(tcp, arg, evdev_autorepeat,
287 					     REP_MAX, "REP_???", XT_INDEXED);
288 		case EV_FF:
289 			return decode_bitset(tcp, arg, evdev_ff_types,
290 					     FF_MAX, "FF_???", XT_SORTED);
291 		case EV_PWR:
292 			tprints(", ");
293 			printnum_int(tcp, arg, "%d");
294 			return RVAL_IOCTL_DECODED;
295 		case EV_FF_STATUS:
296 			return decode_bitset(tcp, arg, evdev_ff_status,
297 					     FF_STATUS_MAX, "FF_STATUS_???",
298 					     XT_INDEXED);
299 		default:
300 			tprints(", ");
301 			printaddr(arg);
302 			return RVAL_IOCTL_DECODED;
303 	}
304 }
305 
306 static int
evdev_read_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)307 evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
308 		 const kernel_ulong_t arg)
309 {
310 	/* fixed-number fixed-length commands */
311 	switch (code) {
312 		case EVIOCGVERSION:
313 			tprints(", ");
314 			printnum_int(tcp, arg, "%#x");
315 			return RVAL_IOCTL_DECODED;
316 		case EVIOCGEFFECTS:
317 			tprints(", ");
318 			printnum_int(tcp, arg, "%u");
319 			return RVAL_IOCTL_DECODED;
320 		case EVIOCGID:
321 			return getid_ioctl(tcp, arg);
322 # ifdef EVIOCGREP
323 		case EVIOCGREP:
324 			return repeat_ioctl(tcp, arg);
325 # endif
326 		case EVIOCGKEYCODE:
327 			return keycode_ioctl(tcp, arg);
328 # ifdef EVIOCGKEYCODE_V2
329 		case EVIOCGKEYCODE_V2:
330 			return keycode_V2_ioctl(tcp, arg);
331 # endif
332 	}
333 
334 	/* fixed-number variable-length commands */
335 	switch (_IOC_NR(code)) {
336 # ifdef EVIOCGMTSLOTS
337 		case _IOC_NR(EVIOCGMTSLOTS(0)):
338 			return mtslots_ioctl(tcp, code, arg);
339 # endif
340 		case _IOC_NR(EVIOCGNAME(0)):
341 		case _IOC_NR(EVIOCGPHYS(0)):
342 		case _IOC_NR(EVIOCGUNIQ(0)):
343 			tprints(", ");
344 			if (syserror(tcp))
345 				printaddr(arg);
346 			else
347 				printstrn(tcp, arg, tcp->u_rval);
348 			return RVAL_IOCTL_DECODED;
349 # ifdef EVIOCGPROP
350 		case _IOC_NR(EVIOCGPROP(0)):
351 			return decode_bitset(tcp, arg, evdev_prop,
352 					     INPUT_PROP_MAX, "PROP_???",
353 					     XT_INDEXED);
354 # endif
355 		case _IOC_NR(EVIOCGSND(0)):
356 			return decode_bitset(tcp, arg, evdev_snd,
357 					     SND_MAX, "SND_???", XT_INDEXED);
358 # ifdef EVIOCGSW
359 		case _IOC_NR(EVIOCGSW(0)):
360 			return decode_bitset(tcp, arg, evdev_switch,
361 					     SW_MAX, "SW_???", XT_INDEXED);
362 # endif
363 		case _IOC_NR(EVIOCGKEY(0)):
364 			return decode_bitset(tcp, arg, evdev_keycode,
365 					     KEY_MAX, "KEY_???", XT_INDEXED);
366 		case _IOC_NR(EVIOCGLED(0)):
367 			return decode_bitset(tcp, arg, evdev_leds,
368 					     LED_MAX, "LED_???", XT_INDEXED);
369 	}
370 
371 	/* multi-number fixed-length commands */
372 	if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
373 		return abs_ioctl(tcp, arg);
374 
375 	/* multi-number variable-length commands */
376 	if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
377 		return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);
378 
379 	return 0;
380 }
381 
382 static int
evdev_write_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)383 evdev_write_ioctl(struct tcb *const tcp, const unsigned int code,
384 		  const kernel_ulong_t arg)
385 {
386 	/* fixed-number fixed-length commands */
387 	switch (code) {
388 # ifdef EVIOCSREP
389 		case EVIOCSREP:
390 			return repeat_ioctl(tcp, arg);
391 # endif
392 		case EVIOCSKEYCODE:
393 			return keycode_ioctl(tcp, arg);
394 # ifdef EVIOCSKEYCODE_V2
395 		case EVIOCSKEYCODE_V2:
396 			return keycode_V2_ioctl(tcp, arg);
397 # endif
398 		case EVIOCRMFF:
399 			tprintf(", %d", (int) arg);
400 			return RVAL_IOCTL_DECODED;
401 		case EVIOCGRAB:
402 # ifdef EVIOCREVOKE
403 		case EVIOCREVOKE:
404 # endif
405 			tprintf(", %" PRI_klu, arg);
406 			return RVAL_IOCTL_DECODED;
407 # ifdef EVIOCSCLOCKID
408 		case EVIOCSCLOCKID:
409 			tprints(", ");
410 			printnum_int(tcp, arg, "%u");
411 			return RVAL_IOCTL_DECODED;
412 # endif
413 		default: {
414 			int rc = evdev_write_ioctl_mpers(tcp, code, arg);
415 
416 			if (rc != RVAL_DECODED)
417 				return rc;
418 		}
419 	}
420 
421 	/* multi-number fixed-length commands */
422 	if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
423 		return abs_ioctl(tcp, arg);
424 
425 	return 0;
426 }
427 
428 void
print_evdev_ff_type(const kernel_ulong_t val)429 print_evdev_ff_type(const kernel_ulong_t val)
430 {
431 	printxval(evdev_ff_types, val, "FF_???");
432 }
433 
434 int
evdev_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)435 evdev_ioctl(struct tcb *const tcp,
436 	    const unsigned int code, const kernel_ulong_t arg)
437 {
438 	switch (_IOC_DIR(code)) {
439 		case _IOC_READ:
440 			if (entering(tcp))
441 				return 0;
442 			return evdev_read_ioctl(tcp, code, arg);
443 		case _IOC_WRITE:
444 			return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED;
445 		default:
446 			return RVAL_DECODED;
447 	}
448 }
449 
450 #endif /* HAVE_LINUX_INPUT_H */
451