Index: strace-4.24/evdev.c =================================================================== --- strace-4.24.orig/evdev.c 2019-06-13 23:42:43.294304862 +0200 +++ strace-4.24/evdev.c 2019-06-13 23:43:35.588294946 +0200 @@ -143,6 +143,14 @@ return RVAL_IOCTL_DECODED; } +# ifndef ROUNDUP_DIV +# define ROUNDUP_DIV(val_, div_) (((val_) + (div_) - 1) / (div_)) +# endif + +# ifndef ROUNDUP +# define ROUNDUP(val_, div_) (ROUNDUP_DIV((val_), (div_)) * (div_)) +# endif + static int decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg, const struct xlat decode_nr[], const unsigned int max_nr, @@ -151,25 +159,36 @@ tprints(", "); unsigned int size; - if ((kernel_ulong_t) tcp->u_rval > max_nr / 8) - size = max_nr; + unsigned int size_bits; + + if ((kernel_ulong_t) tcp->u_rval > max_nr / CHAR_BIT) + size_bits = max_nr; else - size = tcp->u_rval * 8; + size_bits = tcp->u_rval * CHAR_BIT; + + size = ROUNDUP(ROUNDUP_DIV(size_bits, CHAR_BIT), current_wordsize); + + if (syserror(tcp) || !size) { + printaddr(arg); + + return RVAL_IOCTL_DECODED; + } + char decoded_arg[size]; - if (umove_or_printaddr(tcp, arg, &decoded_arg)) + if (umoven_or_printaddr(tcp, arg, size, decoded_arg)) return RVAL_IOCTL_DECODED; tprints("["); int bit_displayed = 0; - int i = next_set_bit(decoded_arg, 0, size); + int i = next_set_bit(decoded_arg, 0, size_bits); if (i < 0) { tprints(" 0 "); } else { printxval_dispatch(decode_nr, decode_nr_size, i, dflt, xt); - while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) { + while ((i = next_set_bit(decoded_arg, i + 1, size_bits)) > 0) { if (abbrev(tcp) && bit_displayed >= 3) { tprints(", ..."); break;