]> granicus.if.org Git - strace/blob - evdev.c
rtnl_neightbl: always decode struct ndt_config and struct ndt_stats
[strace] / evdev.c
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-2019 The strace developers.
5  * All rights reserved.
6  *
7  * SPDX-License-Identifier: LGPL-2.1-or-later
8  */
9
10 #include "defs.h"
11
12 #include "xlat/evdev_abs.h"
13 #include "xlat/evdev_ev.h"
14
15 #ifdef HAVE_LINUX_INPUT_H
16
17 # include <linux/ioctl.h>
18 # include <linux/input.h>
19
20 # include "xlat/evdev_autorepeat.h"
21 # include "xlat/evdev_ff_status.h"
22 # include "xlat/evdev_ff_types.h"
23 # include "xlat/evdev_keycode.h"
24 # include "xlat/evdev_leds.h"
25 # include "xlat/evdev_misc.h"
26 # include "xlat/evdev_mtslots.h"
27 # include "xlat/evdev_prop.h"
28 # include "xlat/evdev_relative_axes.h"
29 # include "xlat/evdev_snd.h"
30 # include "xlat/evdev_switch.h"
31
32 # ifndef SYN_MAX
33 #  define SYN_MAX 0xf
34 # endif
35
36 static int
37 abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
38 {
39         tprints(", ");
40
41         struct input_absinfo absinfo;
42
43         if (!umove_or_printaddr(tcp, arg, &absinfo)) {
44                 tprintf("{value=%u"
45                         ", minimum=%u, ",
46                         absinfo.value,
47                         absinfo.minimum);
48
49                 if (!abbrev(tcp)) {
50                         tprintf("maximum=%u"
51                                 ", fuzz=%u"
52                                 ", flat=%u",
53                                 absinfo.maximum,
54                                 absinfo.fuzz,
55                                 absinfo.flat);
56 # ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
57                         tprintf(", resolution=%u",
58                                 absinfo.resolution);
59 # endif
60                 } else {
61                         tprints("...");
62                 }
63
64                 tprints("}");
65         }
66
67         return RVAL_IOCTL_DECODED;
68 }
69
70 static int
71 keycode_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
72 {
73         tprints(", ");
74
75         unsigned int keycode[2];
76
77         if (!umove_or_printaddr(tcp, arg, &keycode)) {
78                 tprintf("[%u, ", keycode[0]);
79                 printxval(evdev_keycode, keycode[1], "KEY_???");
80                 tprints("]");
81         }
82
83         return RVAL_IOCTL_DECODED;
84 }
85
86 # ifdef EVIOCGKEYCODE_V2
87 static int
88 keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
89 {
90         tprints(", ");
91
92         struct input_keymap_entry ike;
93
94         if (umove_or_printaddr(tcp, arg, &ike))
95                 return RVAL_IOCTL_DECODED;
96
97         tprintf("{flags=%" PRIu8
98                 ", len=%" PRIu8 ", ",
99                 ike.flags,
100                 ike.len);
101
102         if (!abbrev(tcp)) {
103                 unsigned int i;
104
105                 tprintf("index=%" PRIu16 ", keycode=", ike.index);
106                 printxval(evdev_keycode, ike.keycode, "KEY_???");
107                 tprints(", scancode=[");
108                 for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
109                         if (i > 0)
110                                 tprints(", ");
111                         tprintf("%" PRIx8, ike.scancode[i]);
112                 }
113                 tprints("]");
114         } else {
115                 tprints("...");
116         }
117
118         tprints("}");
119
120         return RVAL_IOCTL_DECODED;
121 }
122 # endif /* EVIOCGKEYCODE_V2 */
123
124 static int
125 getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
126 {
127         tprints(", ");
128
129         struct input_id id;
130
131         if (!umove_or_printaddr(tcp, arg, &id))
132                 tprintf("{ID_BUS=%" PRIu16
133                         ", ID_VENDOR=%" PRIu16
134                         ", ID_PRODUCT=%" PRIu16
135                         ", ID_VERSION=%" PRIu16 "}",
136                         id.bustype,
137                         id.vendor,
138                         id.product,
139                         id.version);
140
141         return RVAL_IOCTL_DECODED;
142 }
143
144 static int
145 decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
146               const struct xlat *decode_nr, const unsigned int max_nr,
147               const char *const dflt)
148 {
149         tprints(", ");
150
151         unsigned int size;
152         unsigned int size_bits;
153
154         if ((kernel_ulong_t) tcp->u_rval > max_nr / 8)
155                 size_bits = max_nr;
156         else
157                 size_bits = tcp->u_rval * 8;
158
159         size = ROUNDUP(ROUNDUP_DIV(size_bits, 8), current_wordsize);
160
161         if (syserror(tcp) || !size) {
162                 printaddr(arg);
163
164                 return RVAL_IOCTL_DECODED;
165         }
166
167         char decoded_arg[size];
168
169         if (umove_or_printaddr(tcp, arg, &decoded_arg))
170                 return RVAL_IOCTL_DECODED;
171
172         if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_RAW) {
173                 tprints("[");
174
175                 int bit_displayed = 0;
176                 int i = next_set_bit(decoded_arg, 0, size_bits);
177                 if (i < 0) {
178                         tprints(" 0 ");
179                 } else {
180                         printxval(decode_nr, i, dflt);
181
182                         while ((i = next_set_bit(decoded_arg, i + 1,
183                                                  size_bits)) > 0) {
184                                 if (abbrev(tcp) && bit_displayed >= 3) {
185                                         tprints(", ...");
186                                         break;
187                                 }
188                                 tprints(", ");
189                                 printxval(decode_nr, i, dflt);
190                                 bit_displayed++;
191                         }
192                 }
193
194                 tprints("]");
195         }
196
197         if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
198                 tprints(" /* ");
199
200         if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV) {
201                 uint64_t elem;
202
203                 print_local_array(tcp, decoded_arg, size / current_wordsize,
204                                   &elem, current_wordsize,
205                                   print_xlong_array_member, NULL, 0);
206         }
207
208         if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
209                 tprints(" */");
210
211         return RVAL_IOCTL_DECODED;
212 }
213
214 # ifdef EVIOCGMTSLOTS
215 static int
216 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
217               const kernel_ulong_t arg)
218 {
219         tprints(", ");
220
221         const size_t size = _IOC_SIZE(code) / sizeof(int);
222         if (!size) {
223                 printaddr(arg);
224                 return RVAL_IOCTL_DECODED;
225         }
226
227         int buffer[size];
228
229         if (umove_or_printaddr(tcp, arg, &buffer))
230                 return RVAL_IOCTL_DECODED;
231
232         tprints("{code=");
233         printxval(evdev_mtslots, buffer[0], "ABS_MT_???");
234
235         tprints(", values=[");
236
237         unsigned int i;
238         for (i = 1; i < ARRAY_SIZE(buffer); i++)
239                 tprintf("%s%d", i > 1 ? ", " : "", buffer[i]);
240
241         tprints("]}");
242
243         return RVAL_IOCTL_DECODED;
244 }
245 # endif /* EVIOCGMTSLOTS */
246
247 # if defined EVIOCGREP || defined EVIOCSREP
248 static int
249 repeat_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
250 {
251         tprints(", ");
252         printpair_int(tcp, arg, "%u");
253         return RVAL_IOCTL_DECODED;
254 }
255 # endif /* EVIOCGREP || EVIOCSREP */
256
257 static int
258 bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
259           const kernel_ulong_t arg)
260 {
261         switch (ev_nr) {
262         case 0:
263                 return decode_bitset(tcp, arg, evdev_ev,
264                                      EV_MAX, "EV_???");
265         case EV_KEY:
266                 return decode_bitset(tcp, arg, evdev_keycode,
267                                      KEY_MAX, "KEY_???");
268         case EV_REL:
269                 return decode_bitset(tcp, arg, evdev_relative_axes,
270                                      REL_MAX, "REL_???");
271         case EV_ABS:
272                 return decode_bitset(tcp, arg, evdev_abs,
273                                      ABS_MAX, "ABS_???");
274         case EV_MSC:
275                 return decode_bitset(tcp, arg, evdev_misc,
276                                      MSC_MAX, "MSC_???");
277         case EV_SW:
278                 return decode_bitset(tcp, arg, evdev_switch,
279                                      SW_MAX, "SW_???");
280         case EV_LED:
281                 return decode_bitset(tcp, arg, evdev_leds,
282                                      LED_MAX, "LED_???");
283         case EV_SND:
284                 return decode_bitset(tcp, arg, evdev_snd,
285                                      SND_MAX, "SND_???");
286         case EV_REP:
287                 return decode_bitset(tcp, arg, evdev_autorepeat,
288                                      REP_MAX, "REP_???");
289         case EV_FF:
290                 return decode_bitset(tcp, arg, evdev_ff_types,
291                                      FF_MAX, "FF_???");
292         case EV_PWR:
293                 tprints(", ");
294                 printnum_int(tcp, arg, "%d");
295                 return RVAL_IOCTL_DECODED;
296         case EV_FF_STATUS:
297                 return decode_bitset(tcp, arg, evdev_ff_status,
298                                      FF_STATUS_MAX, "FF_STATUS_???");
299         default:
300                 tprints(", ");
301                 printaddr(arg);
302                 return RVAL_IOCTL_DECODED;
303         }
304 }
305
306 static int
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 # endif
354         case _IOC_NR(EVIOCGSND(0)):
355                 return decode_bitset(tcp, arg, evdev_snd,
356                                      SND_MAX, "SND_???");
357 # ifdef EVIOCGSW
358         case _IOC_NR(EVIOCGSW(0)):
359                 return decode_bitset(tcp, arg, evdev_switch,
360                                      SW_MAX, "SW_???");
361 # endif
362         case _IOC_NR(EVIOCGKEY(0)):
363                 return decode_bitset(tcp, arg, evdev_keycode,
364                                      KEY_MAX, "KEY_???");
365         case _IOC_NR(EVIOCGLED(0)):
366                 return decode_bitset(tcp, arg, evdev_leds,
367                                      LED_MAX, "LED_???");
368         }
369
370         /* multi-number fixed-length commands */
371         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
372                 return abs_ioctl(tcp, arg);
373
374         /* multi-number variable-length commands */
375         if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
376                 return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);
377
378         return 0;
379 }
380
381 static int
382 evdev_write_ioctl(struct tcb *const tcp, const unsigned int code,
383                   const kernel_ulong_t arg)
384 {
385         /* fixed-number fixed-length commands */
386         switch (code) {
387 # ifdef EVIOCSREP
388         case EVIOCSREP:
389                 return repeat_ioctl(tcp, arg);
390 # endif
391         case EVIOCSKEYCODE:
392                 return keycode_ioctl(tcp, arg);
393 # ifdef EVIOCSKEYCODE_V2
394         case EVIOCSKEYCODE_V2:
395                 return keycode_V2_ioctl(tcp, arg);
396 # endif
397         case EVIOCRMFF:
398                 tprintf(", %d", (int) arg);
399                 return RVAL_IOCTL_DECODED;
400         case EVIOCGRAB:
401 # ifdef EVIOCREVOKE
402         case EVIOCREVOKE:
403 # endif
404                 tprintf(", %" PRI_klu, arg);
405                 return RVAL_IOCTL_DECODED;
406 # ifdef EVIOCSCLOCKID
407         case EVIOCSCLOCKID:
408                 tprints(", ");
409                 printnum_int(tcp, arg, "%u");
410                 return RVAL_IOCTL_DECODED;
411 # endif
412         }
413
414         int rc = evdev_write_ioctl_mpers(tcp, code, arg);
415
416         if (rc != RVAL_DECODED)
417                 return rc;
418
419         /* multi-number fixed-length commands */
420         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
421                 return abs_ioctl(tcp, arg);
422
423         return 0;
424 }
425
426 void
427 print_evdev_ff_type(const kernel_ulong_t val)
428 {
429         printxval(evdev_ff_types, val, "FF_???");
430 }
431
432 int
433 evdev_ioctl(struct tcb *const tcp,
434             const unsigned int code, const kernel_ulong_t arg)
435 {
436         switch (_IOC_DIR(code)) {
437         case _IOC_READ:
438                 if (entering(tcp))
439                         return 0;
440                 return evdev_read_ioctl(tcp, code, arg);
441         case _IOC_WRITE:
442                 return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED;
443         default:
444                 return RVAL_DECODED;
445         }
446 }
447
448 #endif /* HAVE_LINUX_INPUT_H */