Blob Blame History Raw
From 8cff8e59d501e41af8de9b0ff0e2f7bf65fc22f2 Mon Sep 17 00:00:00 2001
From: Eugene Syromyatnikov <evgsyr@gmail.com>
Date: Sun, 13 Oct 2019 17:18:38 +0200
Subject: [PATCH 68/76] 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

Conflicts:
	evdev.c
---
 configure.ac             |  4 +++
 evdev.c                  | 75 ++++++++++++++++++++++++++++++++----------------
 xlat/evdev_ioctl_cmds.in | 17 +++++++++++
 3 files changed, 71 insertions(+), 25 deletions(-)
 create mode 100644 xlat/evdev_ioctl_cmds.in

Index: strace-5.1/configure.ac
===================================================================
--- strace-5.1.orig/configure.ac	2020-01-29 12:35:51.722702560 +0100
+++ strace-5.1/configure.ac	2020-01-29 12:37:35.136765878 +0100
@@ -453,6 +453,10 @@
 #include <net/if.h>])
 
 AC_CHECK_HEADERS([linux/input.h], [
+	AC_CHECK_TYPES(m4_normalize([
+		struct input_keymap_entry,
+		struct input_mask
+	]),,, [#include <linux/input.h>])
 	AC_CHECK_MEMBERS([struct input_absinfo.resolution],,, [#include <linux/input.h>])
 ])
 
Index: strace-5.1/evdev.c
===================================================================
--- strace-5.1.orig/evdev.c	2020-01-29 12:35:42.692778989 +0100
+++ strace-5.1/evdev.c	2020-01-29 12:37:35.139765850 +0100
@@ -29,10 +29,59 @@
 # include "xlat/evdev_snd.h"
 # include "xlat/evdev_switch.h"
 
+/** Added by Linux commit v2.6.38-rc1~247^2~1^2~2^2~5 */
+# ifndef INPUT_PROP_MAX
+#  define INPUT_PROP_MAX 0x1f
+# endif
 # ifndef SYN_MAX
 #  define SYN_MAX 0xf
 # endif
 
+/** Added by Linux commit v2.6.37-rc1~5^2~3^2~47 */
+typedef struct {
+	uint8_t  flags;
+	uint8_t  len;
+	uint16_t index;
+	uint32_t keycode;
+	uint8_t  scancode[32];
+} struct_input_keymap_entry;
+
+/** Added by Linux commit v4.4-rc1~11^2~3^2~2 */
+typedef struct {
+	uint32_t type;
+	uint32_t codes_size;
+	uint64_t codes_ptr;
+} struct_input_mask;
+
+# ifdef HAVE_STRUCT_INPUT_KEYMAP_ENTRY
+static_assert(sizeof(struct input_keymap_entry)
+	      == sizeof(struct_input_keymap_entry),
+	      "Unexpected struct input_keymap_entry size, please update "
+	      "the decoder");
+# endif
+# ifdef HAVE_STRUCT_INPUT_MASK
+static_assert(sizeof(struct input_mask) == sizeof(struct_input_mask),
+	      "Unexpected struct input_mask size, please update the decoder");
+# endif
+
+/*
+ * Has to be included after struct_* type definitions, since _IO* macros
+ * used in fallback definitions require them for sizeof().
+ */
+# define XLAT_MACROS_ONLY
+#  include "xlat/evdev_ioctl_cmds.h"
+# undef XLAT_MACROS_ONLY
+
+# ifndef EVIOCGPROP
+#  define EVIOCGPROP(len)	_IOR('E', 0x09, len)
+# endif
+# ifndef EVIOCGMTSLOTS
+#  define EVIOCGMTSLOTS(len)	_IOR('E', 0x0a, len)
+# endif
+# ifndef EVIOCGSW
+#  define EVIOCGSW(len)		_IOR('E', 0x1b, len)
+# endif
+
 const size_t evdev_abs_size = ARRAY_SIZE(evdev_abs) - 1;
 
 static int
@@ -85,13 +134,12 @@
 	return RVAL_IOCTL_DECODED;
 }
 
-# ifdef EVIOCGKEYCODE_V2
 static int
 keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
 {
 	tprints(", ");
 
-	struct input_keymap_entry ike;
+	struct_input_keymap_entry ike;
 
 	if (umove_or_printaddr(tcp, arg, &ike))
 		return RVAL_IOCTL_DECODED;
@@ -121,7 +169,6 @@
 
 	return RVAL_IOCTL_DECODED;
 }
-# endif /* EVIOCGKEYCODE_V2 */
 
 static int
 getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
@@ -201,7 +248,6 @@
 	decode_bitset_((tcp_), (arg_), (decode_nr_), (max_nr_), \
 		       (dflt_), ARRAY_SIZE(decode_nr_) - 1, (xt_))
 
-# ifdef EVIOCGMTSLOTS
 static int
 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
 	      const kernel_ulong_t arg)
@@ -232,9 +278,7 @@
 
 	return RVAL_IOCTL_DECODED;
 }
-# endif /* EVIOCGMTSLOTS */
 
-# if defined EVIOCGREP || defined EVIOCSREP
 static int
 repeat_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
 {
@@ -242,7 +286,6 @@
 	printpair_int(tcp, arg, "%u");
 	return RVAL_IOCTL_DECODED;
 }
-# endif /* EVIOCGREP || EVIOCSREP */
 
 static int
 bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
@@ -310,24 +353,18 @@
 		return RVAL_IOCTL_DECODED;
 	case EVIOCGID:
 		return getid_ioctl(tcp, arg);
-# ifdef EVIOCGREP
 	case EVIOCGREP:
 		return repeat_ioctl(tcp, arg);
-# endif
 	case EVIOCGKEYCODE:
 		return keycode_ioctl(tcp, arg);
-# ifdef EVIOCGKEYCODE_V2
 	case EVIOCGKEYCODE_V2:
 		return keycode_V2_ioctl(tcp, arg);
-# endif
 	}
 
 	/* fixed-number variable-length commands */
 	switch (_IOC_NR(code)) {
-# ifdef EVIOCGMTSLOTS
 	case _IOC_NR(EVIOCGMTSLOTS(0)):
 		return mtslots_ioctl(tcp, code, arg);
-# endif
 	case _IOC_NR(EVIOCGNAME(0)):
 	case _IOC_NR(EVIOCGPHYS(0)):
 	case _IOC_NR(EVIOCGUNIQ(0)):
@@ -337,20 +374,16 @@
 		else
 			printstrn(tcp, arg, tcp->u_rval);
 		return RVAL_IOCTL_DECODED;
-# ifdef EVIOCGPROP
 	case _IOC_NR(EVIOCGPROP(0)):
 		return decode_bitset(tcp, arg, evdev_prop,
 				     INPUT_PROP_MAX, "PROP_???",
 				     XT_INDEXED);
-# endif
 	case _IOC_NR(EVIOCGSND(0)):
 		return decode_bitset(tcp, arg, evdev_snd,
 				     SND_MAX, "SND_???", XT_INDEXED);
-# ifdef EVIOCGSW
 	case _IOC_NR(EVIOCGSW(0)):
 		return decode_bitset(tcp, arg, evdev_switch,
 				     SW_MAX, "SW_???", XT_INDEXED);
-# endif
 	case _IOC_NR(EVIOCGKEY(0)):
 		return decode_bitset(tcp, arg, evdev_keycode,
 				     KEY_MAX, "KEY_???", XT_INDEXED);
@@ -376,31 +409,23 @@
 {
 	/* fixed-number fixed-length commands */
 	switch (code) {
-# ifdef EVIOCSREP
 	case EVIOCSREP:
 		return repeat_ioctl(tcp, arg);
-# endif
 	case EVIOCSKEYCODE:
 		return keycode_ioctl(tcp, arg);
-# ifdef EVIOCSKEYCODE_V2
 	case EVIOCSKEYCODE_V2:
 		return keycode_V2_ioctl(tcp, arg);
-# endif
 	case EVIOCRMFF:
 		tprintf(", %d", (int) arg);
 		return RVAL_IOCTL_DECODED;
 	case EVIOCGRAB:
-# ifdef EVIOCREVOKE
 	case EVIOCREVOKE:
-# endif
 		tprintf(", %" PRI_klu, arg);
 		return RVAL_IOCTL_DECODED;
-# ifdef EVIOCSCLOCKID
 	case EVIOCSCLOCKID:
 		tprints(", ");
 		printnum_int(tcp, arg, "%u");
 		return RVAL_IOCTL_DECODED;
-# endif
 	}
 
 	int rc = evdev_write_ioctl_mpers(tcp, code, arg);
Index: strace-5.1/xlat/evdev_ioctl_cmds.in
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ strace-5.1/xlat/evdev_ioctl_cmds.in	2020-01-29 12:37:35.139765850 +0100
@@ -0,0 +1,17 @@
+EVIOCGVERSION		_IOR('E', 0x01, int)
+EVIOCGID		_IOR('E', 0x02, struct input_id)
+EVIOCGREP		_IOR('E', 0x03, unsigned int[2])
+EVIOCSREP		_IOW('E', 0x03, unsigned int[2])
+EVIOCGKEYCODE		_IOR('E', 0x04, unsigned int[2])
+EVIOCGKEYCODE_V2	_IOR('E', 0x04, struct_input_keymap_entry)
+EVIOCSKEYCODE		_IOW('E', 0x04, unsigned int[2])
+EVIOCSKEYCODE_V2	_IOW('E', 0x04, struct_input_keymap_entry)
+/* struct ff_effect is personality-dependent in size */
+/* EVIOCSFF		_IOW('E', 0x80, struct ff_effect) */
+EVIOCRMFF		_IOW('E', 0x81, int)
+EVIOCGEFFECTS		_IOR('E', 0x84, int)
+EVIOCGRAB		_IOW('E', 0x90, int)
+EVIOCREVOKE		_IOW('E', 0x91, int)
+EVIOCGMASK		_IOR('E', 0x92, struct_input_mask)
+EVIOCSMASK		_IOW('E', 0x93, struct_input_mask)
+EVIOCSCLOCKID		_IOW('E', 0xa0, int)
Index: strace-5.1/xlat/evdev_ioctl_cmds.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ strace-5.1/xlat/evdev_ioctl_cmds.h	2020-01-29 12:38:33.041234361 +0100
@@ -0,0 +1,144 @@
+/* Generated by ./xlat/gen.sh from ./xlat/evdev_ioctl_cmds.in; do not edit. */
+
+#include "gcc_compat.h"
+#include "static_assert.h"
+
+#if defined(EVIOCGVERSION) || (defined(HAVE_DECL_EVIOCGVERSION) && HAVE_DECL_EVIOCGVERSION)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGVERSION) == (_IOR('E', 0x01, int)), "EVIOCGVERSION != _IOR('E', 0x01, int)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGVERSION _IOR('E', 0x01, int)
+#endif
+#if defined(EVIOCGID) || (defined(HAVE_DECL_EVIOCGID) && HAVE_DECL_EVIOCGID)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGID) == (_IOR('E', 0x02, struct input_id)), "EVIOCGID != _IOR('E', 0x02, struct input_id)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGID _IOR('E', 0x02, struct input_id)
+#endif
+#if defined(EVIOCGREP) || (defined(HAVE_DECL_EVIOCGREP) && HAVE_DECL_EVIOCGREP)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGREP) == (_IOR('E', 0x03, unsigned int[2])), "EVIOCGREP != _IOR('E', 0x03, unsigned int[2])");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGREP _IOR('E', 0x03, unsigned int[2])
+#endif
+#if defined(EVIOCSREP) || (defined(HAVE_DECL_EVIOCSREP) && HAVE_DECL_EVIOCSREP)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCSREP) == (_IOW('E', 0x03, unsigned int[2])), "EVIOCSREP != _IOW('E', 0x03, unsigned int[2])");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCSREP _IOW('E', 0x03, unsigned int[2])
+#endif
+#if defined(EVIOCGKEYCODE) || (defined(HAVE_DECL_EVIOCGKEYCODE) && HAVE_DECL_EVIOCGKEYCODE)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGKEYCODE) == (_IOR('E', 0x04, unsigned int[2])), "EVIOCGKEYCODE != _IOR('E', 0x04, unsigned int[2])");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2])
+#endif
+#if defined(EVIOCGKEYCODE_V2) || (defined(HAVE_DECL_EVIOCGKEYCODE_V2) && HAVE_DECL_EVIOCGKEYCODE_V2)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGKEYCODE_V2) == (_IOR('E', 0x04, struct_input_keymap_entry)), "EVIOCGKEYCODE_V2 != _IOR('E', 0x04, struct_input_keymap_entry)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct_input_keymap_entry)
+#endif
+#if defined(EVIOCSKEYCODE) || (defined(HAVE_DECL_EVIOCSKEYCODE) && HAVE_DECL_EVIOCSKEYCODE)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCSKEYCODE) == (_IOW('E', 0x04, unsigned int[2])), "EVIOCSKEYCODE != _IOW('E', 0x04, unsigned int[2])");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2])
+#endif
+#if defined(EVIOCSKEYCODE_V2) || (defined(HAVE_DECL_EVIOCSKEYCODE_V2) && HAVE_DECL_EVIOCSKEYCODE_V2)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCSKEYCODE_V2) == (_IOW('E', 0x04, struct_input_keymap_entry)), "EVIOCSKEYCODE_V2 != _IOW('E', 0x04, struct_input_keymap_entry)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct_input_keymap_entry)
+#endif
+#if defined(EVIOCRMFF) || (defined(HAVE_DECL_EVIOCRMFF) && HAVE_DECL_EVIOCRMFF)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCRMFF) == (_IOW('E', 0x81, int)), "EVIOCRMFF != _IOW('E', 0x81, int)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCRMFF _IOW('E', 0x81, int)
+#endif
+#if defined(EVIOCGEFFECTS) || (defined(HAVE_DECL_EVIOCGEFFECTS) && HAVE_DECL_EVIOCGEFFECTS)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGEFFECTS) == (_IOR('E', 0x84, int)), "EVIOCGEFFECTS != _IOR('E', 0x84, int)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGEFFECTS _IOR('E', 0x84, int)
+#endif
+#if defined(EVIOCGRAB) || (defined(HAVE_DECL_EVIOCGRAB) && HAVE_DECL_EVIOCGRAB)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGRAB) == (_IOW('E', 0x90, int)), "EVIOCGRAB != _IOW('E', 0x90, int)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGRAB _IOW('E', 0x90, int)
+#endif
+#if defined(EVIOCREVOKE) || (defined(HAVE_DECL_EVIOCREVOKE) && HAVE_DECL_EVIOCREVOKE)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCREVOKE) == (_IOW('E', 0x91, int)), "EVIOCREVOKE != _IOW('E', 0x91, int)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCREVOKE _IOW('E', 0x91, int)
+#endif
+#if defined(EVIOCGMASK) || (defined(HAVE_DECL_EVIOCGMASK) && HAVE_DECL_EVIOCGMASK)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCGMASK) == (_IOR('E', 0x92, struct_input_mask)), "EVIOCGMASK != _IOR('E', 0x92, struct_input_mask)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCGMASK _IOR('E', 0x92, struct_input_mask)
+#endif
+#if defined(EVIOCSMASK) || (defined(HAVE_DECL_EVIOCSMASK) && HAVE_DECL_EVIOCSMASK)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCSMASK) == (_IOW('E', 0x93, struct_input_mask)), "EVIOCSMASK != _IOW('E', 0x93, struct_input_mask)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCSMASK _IOW('E', 0x93, struct_input_mask)
+#endif
+#if defined(EVIOCSCLOCKID) || (defined(HAVE_DECL_EVIOCSCLOCKID) && HAVE_DECL_EVIOCSCLOCKID)
+DIAG_PUSH_IGNORE_TAUTOLOGICAL_COMPARE
+static_assert((EVIOCSCLOCKID) == (_IOW('E', 0xa0, int)), "EVIOCSCLOCKID != _IOW('E', 0xa0, int)");
+DIAG_POP_IGNORE_TAUTOLOGICAL_COMPARE
+#else
+# define EVIOCSCLOCKID _IOW('E', 0xa0, int)
+#endif
+
+#ifndef XLAT_MACROS_ONLY
+
+# ifdef IN_MPERS
+
+#  error static const struct xlat evdev_ioctl_cmds in mpers mode
+
+# else
+
+static
+const struct xlat evdev_ioctl_cmds[] = {
+ XLAT(EVIOCGVERSION),
+ XLAT(EVIOCGID),
+ XLAT(EVIOCGREP),
+ XLAT(EVIOCSREP),
+ XLAT(EVIOCGKEYCODE),
+ XLAT(EVIOCGKEYCODE_V2),
+ XLAT(EVIOCSKEYCODE),
+ XLAT(EVIOCSKEYCODE_V2),
+
+
+ XLAT(EVIOCRMFF),
+ XLAT(EVIOCGEFFECTS),
+ XLAT(EVIOCGRAB),
+ XLAT(EVIOCREVOKE),
+ XLAT(EVIOCGMASK),
+ XLAT(EVIOCSMASK),
+ XLAT(EVIOCSCLOCKID),
+ XLAT_END
+};
+
+# endif /* !IN_MPERS */
+
+#endif /* !XLAT_MACROS_ONLY */