From 8a18f80a372874da930e0ec22c4c6865a0268eb0 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 27 May 2016 00:40:10 +0000 Subject: [PATCH] evdev.c: reorder ioctl command checks Change the order of ioctl command cheks to match the kernel: 1st, check for fixed-number fixed-length commands, 2nd, check for fixed-number variable-length commands, 3rd, check for multi-number fixed-length commands, 4thm check for multi-number variable-length commands. * evdev.c (evdev_read_ioctl, evdev_write_ioctl): Reorder ioctl command checks. --- evdev.c | 120 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/evdev.c b/evdev.c index dd068a86..dda8f54e 100644 --- a/evdev.c +++ b/evdev.c @@ -308,59 +308,12 @@ repeat_ioctl(struct tcb *tcp, long arg) # endif /* EVIOCGREP || EVIOCSREP */ static int -evdev_read_ioctl(struct tcb *tcp, const unsigned int code, long arg) +evdev_read_ioctl(struct tcb *tcp, const unsigned int code, const long arg) { if (syserror(tcp)) return 0; - if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) { - switch (_IOC_NR(code) - 0x20) { - case EV_SYN: - return decode_bitset(tcp, arg, evdev_sync, - SYN_MAX, "SYN_???"); - case EV_KEY: - return decode_bitset(tcp, arg, evdev_keycode, - KEY_MAX, "KEY_???"); - case EV_REL: - return decode_bitset(tcp, arg, evdev_relative_axes, - REL_MAX, "REL_???"); - case EV_ABS: - return decode_bitset(tcp, arg, - evdev_abs, ABS_MAX, "ABS_???"); - case EV_MSC: - return decode_bitset(tcp, arg, - evdev_misc, MSC_MAX, "MSC_???"); -# ifdef EV_SW - case EV_SW: - return decode_bitset(tcp, arg, - evdev_switch, SW_MAX, "SW_???"); -# endif - case EV_LED: - return decode_bitset(tcp, arg, - evdev_leds, LED_MAX, "LED_???"); - case EV_SND: - return decode_bitset(tcp, arg, - evdev_snd, SND_MAX, "SND_???"); - case EV_REP: - return decode_bitset(tcp, arg, evdev_autorepeat, - REP_MAX, "REP_???"); - case EV_FF: - return decode_bitset(tcp, arg, evdev_ff_types, - FF_MAX, "FF_???"); - case EV_PWR: - printnum_int(tcp, arg, "%d"); - return 1; - case EV_FF_STATUS: - return decode_bitset(tcp, arg, evdev_ff_status, - FF_STATUS_MAX, "FF_STATUS_???"); - default: - return 0; - } - } - - if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) - return abs_ioctl(tcp, arg); - + /* fixed-number fixed-length commands */ switch (code) { case EVIOCGVERSION: tprints(", "); @@ -384,6 +337,7 @@ evdev_read_ioctl(struct tcb *tcp, const unsigned int code, long arg) # endif } + /* fixed-number variable-length commands */ switch (_IOC_NR(code)) { # ifdef EVIOCGMTSLOTS case _IOC_NR(EVIOCGMTSLOTS(0)): @@ -414,17 +368,65 @@ evdev_read_ioctl(struct tcb *tcp, const unsigned int code, long arg) case _IOC_NR(EVIOCGLED(0)): return decode_bitset(tcp, arg, evdev_leds, LED_MAX, "LED_???"); - default: - return 0; } + + /* multi-number fixed-length commands */ + if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) + return abs_ioctl(tcp, arg); + + /* multi-number variable-length commands */ + if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) { + switch (_IOC_NR(code) - 0x20) { + case EV_SYN: + return decode_bitset(tcp, arg, evdev_sync, + SYN_MAX, "SYN_???"); + case EV_KEY: + return decode_bitset(tcp, arg, evdev_keycode, + KEY_MAX, "KEY_???"); + case EV_REL: + return decode_bitset(tcp, arg, evdev_relative_axes, + REL_MAX, "REL_???"); + case EV_ABS: + return decode_bitset(tcp, arg, + evdev_abs, ABS_MAX, "ABS_???"); + case EV_MSC: + return decode_bitset(tcp, arg, + evdev_misc, MSC_MAX, "MSC_???"); +# ifdef EV_SW + case EV_SW: + return decode_bitset(tcp, arg, + evdev_switch, SW_MAX, "SW_???"); +# endif + case EV_LED: + return decode_bitset(tcp, arg, + evdev_leds, LED_MAX, "LED_???"); + case EV_SND: + return decode_bitset(tcp, arg, + evdev_snd, SND_MAX, "SND_???"); + case EV_REP: + return decode_bitset(tcp, arg, evdev_autorepeat, + REP_MAX, "REP_???"); + case EV_FF: + return decode_bitset(tcp, arg, evdev_ff_types, + FF_MAX, "FF_???"); + case EV_PWR: + printnum_int(tcp, arg, "%d"); + return 1; + case EV_FF_STATUS: + return decode_bitset(tcp, arg, evdev_ff_status, + FF_STATUS_MAX, "FF_STATUS_???"); + default: + return 0; + } + } + + return 0; } static int -evdev_write_ioctl(struct tcb *tcp, const unsigned int code, long arg) +evdev_write_ioctl(struct tcb *tcp, const unsigned int code, const long arg) { - if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) - return abs_ioctl(tcp, arg); - + /* fixed-number fixed-length commands */ switch (code) { # ifdef EVIOCSREP case EVIOCSREP: @@ -449,9 +451,13 @@ evdev_write_ioctl(struct tcb *tcp, const unsigned int code, long arg) tprints(", "); printnum_int(tcp, arg, "%u"); return 1; - default: - return 0; } + + /* multi-number fixed-length commands */ + if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) + return abs_ioctl(tcp, arg); + + return 0; } int -- 2.50.1