Browse Source

evdev: do not rely on EVIOC* constants provided in <linux/input.h>

* xlat/evdev_ioctl_cmds.in: New file.
* configure.ac (AC_CHECK_HEADERS([linux/input.h])): Check for struct
input_keymap_entry and struct input_mask.
* evdev.c [!INPUT_PROP_MAX] (INPUT_PROP_MAX): New macro definition.
(struct_input_keymap_entry, struct_input_mask): New typedefs.
[HAVE_STRUCT_INPUT_KEYMAP_ENTRY]: Add a static_assert to check
that sizeof(struct input_keymap_entry) has the expected value.
[HAVE_STRUCT_INPUT_MASK]: Add a static_assert to check
that sizeof(struct input_mask) has the expected value.
[!EVIOCGPROP] (EVIOCGPROP): New macro definition.
[!EVIOCGMTSLOTS] (EVIOCGMTSLOTS): Likewise.
[!EVIOCGSW] (EVIOCGSW): Likewise.
[!EVIOCGKEYCODE_V2] (keycode_V2_ioctl): Remove guard.
(keycode_V2_ioctl): Change type of ike to struct_input_keymap_entry.
[!EVIOCGMTSLOTS] (mtslots_ioctl): Remove guard.
[!EVIOCGREP || EVIOCSREP] (repeat_ioctl): Likewise.
(evdev_read_ioctl) [!EVIOCGREP] <case EVIOCGREP>: Likewise.
(evdev_read_ioctl) [!EVIOCGKEYCODE_V2] <case EVIOCGKEYCODE_V2>:
Likewise.
(evdev_read_ioctl) [!EVIOCGMTSLOTS] <case EVIOCGMTSLOTS>: Likewise.
(evdev_read_ioctl) [!EVIOCGPROP] <case EVIOCGPROP>: Likewise.
(evdev_read_ioctl) [!EVIOCGSW] <case EVIOCGSW>: Likewise.
(evdev_write_ioctl) [!EVIOCSREP] <case EVIOCSREP>: Likewise.
(evdev_write_ioctl) [!EVIOCSKEYCODE_V2] <case EVIOCSKEYCODE_V2>: Likewise.
(evdev_write_ioctl) [!EVIOCREVOKE] <case EVIOCREVOKE>: Likewise.
(evdev_write_ioctl) [!EVIOCSCLOCKID] <case EVIOCSCLOCKID>: Likewise.

References: https://bugzilla.redhat.com/show_bug.cgi?id=1758201
Eugene Syromyatnikov 2 months ago
parent
commit
73bfda40f8
3 changed files with 71 additions and 25 deletions
  1. 4
    0
      configure.ac
  2. 50
    25
      evdev.c
  3. 17
    0
      xlat/evdev_ioctl_cmds.in

+ 4
- 0
configure.ac View File

@@ -468,6 +468,10 @@ AC_CHECK_HEADERS(m4_normalize([
468 468
 #include <net/if.h>])
469 469
 
470 470
 AC_CHECK_HEADERS([linux/input.h], [
471
+	AC_CHECK_TYPES(m4_normalize([
472
+		struct input_keymap_entry,
473
+		struct input_mask
474
+	]),,, [#include <linux/input.h>])
471 475
 	AC_CHECK_MEMBERS([struct input_absinfo.resolution],,, [#include <linux/input.h>])
472 476
 ])
473 477
 

+ 50
- 25
evdev.c View File

@@ -29,10 +29,59 @@
29 29
 # include "xlat/evdev_snd.h"
30 30
 # include "xlat/evdev_switch.h"
31 31
 
32
+/** Added by Linux commit v2.6.38-rc1~247^2~1^2~2^2~5 */
33
+# ifndef INPUT_PROP_MAX
34
+#  define INPUT_PROP_MAX 0x1f
35
+# endif
32 36
 # ifndef SYN_MAX
33 37
 #  define SYN_MAX 0xf
34 38
 # endif
35 39
 
40
+/** Added by Linux commit v2.6.37-rc1~5^2~3^2~47 */
41
+typedef struct {
42
+	uint8_t  flags;
43
+	uint8_t  len;
44
+	uint16_t index;
45
+	uint32_t keycode;
46
+	uint8_t  scancode[32];
47
+} struct_input_keymap_entry;
48
+
49
+/** Added by Linux commit v4.4-rc1~11^2~3^2~2 */
50
+typedef struct {
51
+	uint32_t type;
52
+	uint32_t codes_size;
53
+	uint64_t codes_ptr;
54
+} struct_input_mask;
55
+
56
+# ifdef HAVE_STRUCT_INPUT_KEYMAP_ENTRY
57
+static_assert(sizeof(struct input_keymap_entry)
58
+	      == sizeof(struct_input_keymap_entry),
59
+	      "Unexpected struct input_keymap_entry size, please update "
60
+	      "the decoder");
61
+# endif
62
+# ifdef HAVE_STRUCT_INPUT_MASK
63
+static_assert(sizeof(struct input_mask) == sizeof(struct_input_mask),
64
+	      "Unexpected struct input_mask size, please update the decoder");
65
+# endif
66
+
67
+/*
68
+ * Has to be included after struct_* type definitions, since _IO* macros
69
+ * used in fallback definitions require them for sizeof().
70
+ */
71
+# define XLAT_MACROS_ONLY
72
+#  include "xlat/evdev_ioctl_cmds.h"
73
+# undef XLAT_MACROS_ONLY
74
+
75
+# ifndef EVIOCGPROP
76
+#  define EVIOCGPROP(len)	_IOR('E', 0x09, len)
77
+# endif
78
+# ifndef EVIOCGMTSLOTS
79
+#  define EVIOCGMTSLOTS(len)	_IOR('E', 0x0a, len)
80
+# endif
81
+# ifndef EVIOCGSW
82
+#  define EVIOCGSW(len)		_IOR('E', 0x1b, len)
83
+# endif
84
+
36 85
 static int
37 86
 abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
38 87
 {
@@ -83,13 +132,12 @@ keycode_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
83 132
 	return RVAL_IOCTL_DECODED;
84 133
 }
85 134
 
86
-# ifdef EVIOCGKEYCODE_V2
87 135
 static int
88 136
 keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
89 137
 {
90 138
 	tprints(", ");
91 139
 
92
-	struct input_keymap_entry ike;
140
+	struct_input_keymap_entry ike;
93 141
 
94 142
 	if (umove_or_printaddr(tcp, arg, &ike))
95 143
 		return RVAL_IOCTL_DECODED;
@@ -119,7 +167,6 @@ keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
119 167
 
120 168
 	return RVAL_IOCTL_DECODED;
121 169
 }
122
-# endif /* EVIOCGKEYCODE_V2 */
123 170
 
124 171
 static int
125 172
 getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
@@ -211,7 +258,6 @@ decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
211 258
 	return RVAL_IOCTL_DECODED;
212 259
 }
213 260
 
214
-# ifdef EVIOCGMTSLOTS
215 261
 static int
216 262
 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
217 263
 	      const kernel_ulong_t arg)
@@ -242,9 +288,7 @@ mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
242 288
 
243 289
 	return RVAL_IOCTL_DECODED;
244 290
 }
245
-# endif /* EVIOCGMTSLOTS */
246 291
 
247
-# if defined EVIOCGREP || defined EVIOCSREP
248 292
 static int
249 293
 repeat_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
250 294
 {
@@ -252,7 +296,6 @@ repeat_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
252 296
 	printpair_int(tcp, arg, "%u");
253 297
 	return RVAL_IOCTL_DECODED;
254 298
 }
255
-# endif /* EVIOCGREP || EVIOCSREP */
256 299
 
257 300
 static int
258 301
 bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
@@ -319,24 +362,18 @@ evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
319 362
 		return RVAL_IOCTL_DECODED;
320 363
 	case EVIOCGID:
321 364
 		return getid_ioctl(tcp, arg);
322
-# ifdef EVIOCGREP
323 365
 	case EVIOCGREP:
324 366
 		return repeat_ioctl(tcp, arg);
325
-# endif
326 367
 	case EVIOCGKEYCODE:
327 368
 		return keycode_ioctl(tcp, arg);
328
-# ifdef EVIOCGKEYCODE_V2
329 369
 	case EVIOCGKEYCODE_V2:
330 370
 		return keycode_V2_ioctl(tcp, arg);
331
-# endif
332 371
 	}
333 372
 
334 373
 	/* fixed-number variable-length commands */
335 374
 	switch (_IOC_NR(code)) {
336
-# ifdef EVIOCGMTSLOTS
337 375
 	case _IOC_NR(EVIOCGMTSLOTS(0)):
338 376
 		return mtslots_ioctl(tcp, code, arg);
339
-# endif
340 377
 	case _IOC_NR(EVIOCGNAME(0)):
341 378
 	case _IOC_NR(EVIOCGPHYS(0)):
342 379
 	case _IOC_NR(EVIOCGUNIQ(0)):
@@ -346,19 +383,15 @@ evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
346 383
 		else
347 384
 			printstrn(tcp, arg, tcp->u_rval);
348 385
 		return RVAL_IOCTL_DECODED;
349
-# ifdef EVIOCGPROP
350 386
 	case _IOC_NR(EVIOCGPROP(0)):
351 387
 		return decode_bitset(tcp, arg, evdev_prop,
352 388
 				     INPUT_PROP_MAX, "PROP_???");
353
-# endif
354 389
 	case _IOC_NR(EVIOCGSND(0)):
355 390
 		return decode_bitset(tcp, arg, evdev_snd,
356 391
 				     SND_MAX, "SND_???");
357
-# ifdef EVIOCGSW
358 392
 	case _IOC_NR(EVIOCGSW(0)):
359 393
 		return decode_bitset(tcp, arg, evdev_switch,
360 394
 				     SW_MAX, "SW_???");
361
-# endif
362 395
 	case _IOC_NR(EVIOCGKEY(0)):
363 396
 		return decode_bitset(tcp, arg, evdev_keycode,
364 397
 				     KEY_MAX, "KEY_???");
@@ -384,31 +417,23 @@ evdev_write_ioctl(struct tcb *const tcp, const unsigned int code,
384 417
 {
385 418
 	/* fixed-number fixed-length commands */
386 419
 	switch (code) {
387
-# ifdef EVIOCSREP
388 420
 	case EVIOCSREP:
389 421
 		return repeat_ioctl(tcp, arg);
390
-# endif
391 422
 	case EVIOCSKEYCODE:
392 423
 		return keycode_ioctl(tcp, arg);
393
-# ifdef EVIOCSKEYCODE_V2
394 424
 	case EVIOCSKEYCODE_V2:
395 425
 		return keycode_V2_ioctl(tcp, arg);
396
-# endif
397 426
 	case EVIOCRMFF:
398 427
 		tprintf(", %d", (int) arg);
399 428
 		return RVAL_IOCTL_DECODED;
400 429
 	case EVIOCGRAB:
401
-# ifdef EVIOCREVOKE
402 430
 	case EVIOCREVOKE:
403
-# endif
404 431
 		tprintf(", %" PRI_klu, arg);
405 432
 		return RVAL_IOCTL_DECODED;
406
-# ifdef EVIOCSCLOCKID
407 433
 	case EVIOCSCLOCKID:
408 434
 		tprints(", ");
409 435
 		printnum_int(tcp, arg, "%u");
410 436
 		return RVAL_IOCTL_DECODED;
411
-# endif
412 437
 	}
413 438
 
414 439
 	int rc = evdev_write_ioctl_mpers(tcp, code, arg);

+ 17
- 0
xlat/evdev_ioctl_cmds.in View File

@@ -0,0 +1,17 @@
1
+EVIOCGVERSION		_IOR('E', 0x01, int)
2
+EVIOCGID		_IOR('E', 0x02, struct input_id)
3
+EVIOCGREP		_IOR('E', 0x03, unsigned int[2])
4
+EVIOCSREP		_IOW('E', 0x03, unsigned int[2])
5
+EVIOCGKEYCODE		_IOR('E', 0x04, unsigned int[2])
6
+EVIOCGKEYCODE_V2	_IOR('E', 0x04, struct_input_keymap_entry)
7
+EVIOCSKEYCODE		_IOW('E', 0x04, unsigned int[2])
8
+EVIOCSKEYCODE_V2	_IOW('E', 0x04, struct_input_keymap_entry)
9
+/* struct ff_effect is personality-dependent in size */
10
+/* EVIOCSFF		_IOW('E', 0x80, struct ff_effect) */
11
+EVIOCRMFF		_IOW('E', 0x81, int)
12
+EVIOCGEFFECTS		_IOR('E', 0x84, int)
13
+EVIOCGRAB		_IOW('E', 0x90, int)
14
+EVIOCREVOKE		_IOW('E', 0x91, int)
15
+EVIOCGMASK		_IOR('E', 0x92, struct_input_mask)
16
+EVIOCSMASK		_IOW('E', 0x93, struct_input_mask)
17
+EVIOCSCLOCKID		_IOW('E', 0xa0, int)

Loading…
Cancel
Save