From 8cff8e59d501e41af8de9b0ff0e2f7bf65fc22f2 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Sun, 13 Oct 2019 17:18:38 +0200 Subject: [PATCH 68/76] evdev: do not rely on EVIOC* constants provided in * 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] : Likewise. (evdev_read_ioctl) [!EVIOCGKEYCODE_V2] : Likewise. (evdev_read_ioctl) [!EVIOCGMTSLOTS] : Likewise. (evdev_read_ioctl) [!EVIOCGPROP] : Likewise. (evdev_read_ioctl) [!EVIOCGSW] : Likewise. (evdev_write_ioctl) [!EVIOCSREP] : Likewise. (evdev_write_ioctl) [!EVIOCSKEYCODE_V2] : Likewise. (evdev_write_ioctl) [!EVIOCREVOKE] : Likewise. (evdev_write_ioctl) [!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 ]) AC_CHECK_HEADERS([linux/input.h], [ + AC_CHECK_TYPES(m4_normalize([ + struct input_keymap_entry, + struct input_mask + ]),,, [#include ]) AC_CHECK_MEMBERS([struct input_absinfo.resolution],,, [#include ]) ]) 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 */