From cdd8206af74fcb961f0179e21eacf5d55d23f0ac Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Fri, 12 Jul 2019 14:31:44 +0200 Subject: [PATCH 3/3] tests: test evdev bitset decoding more thoroughly * tests/ioctl_evdev-success-v.test: Inject various values. * tests/ioctl_evdev-success.test: Likewise. * tests/ioctl_evdev-success.c (NUM_WORDS): New macro. (struct evdev_check): Constify arg_ptr and print_arg args. (invoke_test_syscall, test_evdev, print_input_absinfo, print_input_id, print_mtslots): Add const qualifiers. (print_getbit): Add const qualifiers, rewrite to expect trailing NULL in the string array instead of leading string count. (main): Set size for ev_more, ev_less, ev_zero arrays; replace leading count element in ev_more_str, ev_less_str, ev_zero_str with trailing NULL; replace ev_more_str and ev_less_str with ev_more_str_2/ev_less_str_2 and ev_more_str_3/ev_less_str_3 that differ by presence of flags that reside beyond first two bytes; add static and const qualifiers where possible; add key/key_sts_8/key_str_16 values; update a to provide either ev_more_str_2 or ev_more_str_3 and either key_str_8 or key_str_16 depending on inject_retval value. --- tests/ioctl_evdev-success-v.test | 15 +++--- tests/ioctl_evdev-success.c | 100 ++++++++++++++++++++++++++------------- tests/ioctl_evdev-success.test | 15 +++--- 3 files changed, 84 insertions(+), 46 deletions(-) Index: strace-5.1/tests/ioctl_evdev-success-v.test =================================================================== --- strace-5.1.orig/tests/ioctl_evdev-success-v.test 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests/ioctl_evdev-success-v.test 2019-08-29 12:08:51.568168577 +0200 @@ -8,11 +8,14 @@ . "${srcdir=.}/scno_tampering.sh" : ${IOCTL_INJECT_START=256} -: ${IOCTL_INJECT_RETVAL=8} run_prog -run_strace -a16 -v -e trace=ioctl \ - -e inject=ioctl:retval="${IOCTL_INJECT_RETVAL}":when="${IOCTL_INJECT_START}+" \ - ../ioctl_evdev-success-v "${IOCTL_INJECT_START}" "${IOCTL_INJECT_RETVAL}"> "$EXP" -grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT" -match_diff "$OUT" "$EXP" + +for ret in 0 2 8 15 16; do + run_strace -a16 -v -e trace=ioctl \ + -e inject=ioctl:retval="${ret}":when="${IOCTL_INJECT_START}+" \ + ../ioctl_evdev-success-v \ + "${IOCTL_INJECT_START}" "${ret}"> "$EXP.$ret" + grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT.$ret" + match_diff "$OUT.$ret" "$EXP.$ret" +done Index: strace-5.1/tests/ioctl_evdev-success.c =================================================================== --- strace-5.1.orig/tests/ioctl_evdev-success.c 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests/ioctl_evdev-success.c 2019-08-29 12:08:51.568168577 +0200 @@ -9,6 +9,7 @@ #ifdef HAVE_LINUX_INPUT_H +# include # include # include # include @@ -16,17 +17,19 @@ # include # include "print_fields.h" +# define NUM_WORDS 4 + static const char *errstr; struct evdev_check { unsigned long cmd; const char *cmd_str; - void *arg_ptr; - void (*print_arg)(long rc, void *ptr, void *arg); + const void *arg_ptr; + void (*print_arg)(long rc, const void *ptr, const void *arg); }; static long -invoke_test_syscall(unsigned long cmd, void *p) +invoke_test_syscall(unsigned long cmd, const void *p) { long rc = ioctl(-1, cmd, p); errstr = sprintrc(rc); @@ -38,7 +41,7 @@ } static void -test_evdev(struct evdev_check *check, void *arg) +test_evdev(struct evdev_check *check, const void *arg) { long rc = invoke_test_syscall(check->cmd, check->arg_ptr); printf("ioctl(-1, %s, ", check->cmd_str); @@ -50,9 +53,9 @@ } static void -print_input_absinfo(long rc, void *ptr, void *arg) +print_input_absinfo(long rc, const void *ptr, const void *arg) { - struct input_absinfo *absinfo = ptr; + const struct input_absinfo *absinfo = ptr; if (rc < 0) { printf("%p", absinfo); @@ -74,9 +77,9 @@ } static void -print_input_id(long rc, void *ptr, void *arg) +print_input_id(long rc, const void *ptr, const void *arg) { - struct input_id *id = ptr; + const struct input_id *id = ptr; if (rc < 0) { printf("%p", id); @@ -91,10 +94,10 @@ # ifdef EVIOCGMTSLOTS static void -print_mtslots(long rc, void *ptr, void *arg) +print_mtslots(long rc, const void *ptr, const void *arg) { - int *buffer = ptr; - const char **str = arg; + const int *buffer = ptr; + const char * const * str = arg; int num = atoi(*(str + 1)); if (rc < 0) { @@ -111,27 +114,26 @@ # endif static void -print_getbit(long rc, void *ptr, void *arg) +print_getbit(long rc, const void *ptr, const void *arg) { - const char **str = arg; - int num = atoi(*str); + const char * const *str = arg; - if (rc < 0) { + if (rc <= 0) { printf("%p", ptr); return; } printf("["); - printf("%s", *(str + 1)); - for (unsigned int i = 2; i <= (unsigned) num; i++) { + for (unsigned long i = 0; str[i]; i++) { # if ! VERBOSE - if (i > 4) { + if (i >= 4) { printf(", ..."); break; } # endif - printf(", "); - printf("%s", *(str + i)); + if (i) + printf(", "); + printf("%s", str[i]); } printf("]"); } @@ -177,6 +179,7 @@ TAIL_ALLOC_OBJECT_CONST_PTR(struct input_id, id); TAIL_ALLOC_OBJECT_CONST_PTR(struct input_absinfo, absinfo); TAIL_ALLOC_OBJECT_CONST_PTR(int, bad_addr_slot); + # ifdef EVIOCGMTSLOTS int mtslots[] = { ABS_MT_SLOT, 1, 3 }; /* we use the second element to indicate the number of values */ @@ -190,36 +193,65 @@ const char *invalid_mtslot_str[] = { invalid_str, "1", "1" }; # endif + enum { ULONG_BIT = sizeof(unsigned long) * 8 }; + /* set more than 4 bits */ - unsigned long ev_more[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED | 1 << EV_SND | 1 << EV_PWR }; - /* we use the first element to indicate the number of set bits */ - /* ev_more_str[0] is "5" so the number of set bits is 5 */ - const char *ev_more_str[] = { "5", "EV_ABS", "EV_MSC", "EV_LED", "EV_SND", "EV_PWR" }; + static const unsigned long ev_more[NUM_WORDS] = { + 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED | 1 << EV_SND + | 1 << EV_PWR }; + static const char * const ev_more_str_2[] = { + "EV_ABS", "EV_MSC", NULL }; + static const char * const ev_more_str_3[] = { + "EV_ABS", "EV_MSC", "EV_LED", "EV_SND", "EV_PWR", NULL }; /* set less than 4 bits */ - unsigned long ev_less[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED }; - const char *ev_less_str[] = { "3", "EV_ABS", "EV_MSC", "EV_LED" }; + static const unsigned long ev_less[NUM_WORDS] = { + 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED }; + static const char * const ev_less_str_2[] = { + "EV_ABS", "EV_MSC", NULL }; + static const char * const ev_less_str_3[] = { + "EV_ABS", "EV_MSC", "EV_LED", NULL }; /* set zero bit */ - unsigned long ev_zero[] = { 0x0 }; - const char *ev_zero_str[] = { "0", " 0 " }; + static const unsigned long ev_zero[NUM_WORDS] = { 0x0 }; + static const char * const ev_zero_str[] = { " 0 ", NULL }; /* KEY_MAX is 0x2ff which is greater than retval * 8 */ - unsigned long key[] = { 1 << KEY_1 | 1 << KEY_2, 0 }; - const char *key_str[] = { "2", "KEY_1", "KEY_2" }; + static const unsigned long key[NUM_WORDS] = { + 1 << KEY_1 | 1 << KEY_2, + [ KEY_F12 / ULONG_BIT ] = 1 << (KEY_F12 % ULONG_BIT) }; + + static const char * const key_str_8[] = { + "KEY_1", "KEY_2", NULL }; + static const char * const key_str_16[] = { + "KEY_1", "KEY_2", "KEY_F12", NULL }; + + assert(sizeof(ev_more) >= (unsigned long) inject_retval); + assert(sizeof(ev_less) >= (unsigned long) inject_retval); + assert(sizeof(ev_zero) >= (unsigned long) inject_retval); + assert(sizeof(key) >= (unsigned long) inject_retval); struct { struct evdev_check check; - void *ptr; + const void *ptr; } a[] = { { { ARG_STR(EVIOCGID), id, print_input_id }, NULL }, { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo }, NULL }, { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL }, { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL }, - { { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit }, &ev_more_str }, - { { ARG_STR(EVIOCGBIT(0, 0)), ev_less, print_getbit }, &ev_less_str }, + { { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit }, + inject_retval * 8 <= EV_LED + ? (const void *) &ev_more_str_2 + : (const void *) &ev_more_str_3 }, + { { ARG_STR(EVIOCGBIT(0, 0)), ev_less, print_getbit }, + inject_retval * 8 <= EV_LED + ? (const void *) &ev_less_str_2 + : (const void *) &ev_less_str_3 }, { { ARG_STR(EVIOCGBIT(0, 0)), ev_zero, print_getbit }, &ev_zero_str }, - { { ARG_STR(EVIOCGBIT(EV_KEY, 0)), key, print_getbit }, &key_str}, + { { ARG_STR(EVIOCGBIT(EV_KEY, 0)), key, print_getbit }, + inject_retval * 8 <= KEY_F12 + ? (const void *) &key_str_8 + : (const void *) &key_str_16 }, # ifdef EVIOCGMTSLOTS { { ARG_STR(EVIOCGMTSLOTS(12)), mtslots, print_mtslots }, &mtslots_str }, { { ARG_STR(EVIOCGMTSLOTS(8)), invalid_mtslot, print_mtslots }, &invalid_mtslot_str } Index: strace-5.1/tests/ioctl_evdev-success.test =================================================================== --- strace-5.1.orig/tests/ioctl_evdev-success.test 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests/ioctl_evdev-success.test 2019-08-29 12:08:51.568168577 +0200 @@ -8,11 +8,14 @@ . "${srcdir=.}/scno_tampering.sh" : ${IOCTL_INJECT_START=256} -: ${IOCTL_INJECT_RETVAL=8} run_prog -run_strace -a16 -e trace=ioctl \ - -e inject=ioctl:retval="${IOCTL_INJECT_RETVAL}":when="${IOCTL_INJECT_START}+" \ - ../ioctl_evdev-success "${IOCTL_INJECT_START}" "${IOCTL_INJECT_RETVAL}"> "$EXP" -grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT" -match_diff "$OUT" "$EXP" + +for ret in 0 2 8 15 16; do + run_strace -a16 -e trace=ioctl \ + -e inject=ioctl:retval="${ret}":when="${IOCTL_INJECT_START}+" \ + ../ioctl_evdev-success \ + "${IOCTL_INJECT_START}" "${ret}"> "$EXP.${ret}" + grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT.$ret" + match_diff "$OUT.$ret" "$EXP.$ret" +done Index: strace-5.1/tests-m32/ioctl_evdev-success-v.test =================================================================== --- strace-5.1.orig/tests-m32/ioctl_evdev-success-v.test 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests-m32/ioctl_evdev-success-v.test 2019-08-29 12:08:51.568168577 +0200 @@ -8,11 +8,14 @@ . "${srcdir=.}/scno_tampering.sh" : ${IOCTL_INJECT_START=256} -: ${IOCTL_INJECT_RETVAL=8} run_prog -run_strace -a16 -v -e trace=ioctl \ - -e inject=ioctl:retval="${IOCTL_INJECT_RETVAL}":when="${IOCTL_INJECT_START}+" \ - ../ioctl_evdev-success-v "${IOCTL_INJECT_START}" "${IOCTL_INJECT_RETVAL}"> "$EXP" -grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT" -match_diff "$OUT" "$EXP" + +for ret in 0 2 8 15 16; do + run_strace -a16 -v -e trace=ioctl \ + -e inject=ioctl:retval="${ret}":when="${IOCTL_INJECT_START}+" \ + ../ioctl_evdev-success-v \ + "${IOCTL_INJECT_START}" "${ret}"> "$EXP.$ret" + grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT.$ret" + match_diff "$OUT.$ret" "$EXP.$ret" +done Index: strace-5.1/tests-m32/ioctl_evdev-success.test =================================================================== --- strace-5.1.orig/tests-m32/ioctl_evdev-success.test 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests-m32/ioctl_evdev-success.test 2019-08-29 12:08:51.568168577 +0200 @@ -8,11 +8,14 @@ . "${srcdir=.}/scno_tampering.sh" : ${IOCTL_INJECT_START=256} -: ${IOCTL_INJECT_RETVAL=8} run_prog -run_strace -a16 -e trace=ioctl \ - -e inject=ioctl:retval="${IOCTL_INJECT_RETVAL}":when="${IOCTL_INJECT_START}+" \ - ../ioctl_evdev-success "${IOCTL_INJECT_START}" "${IOCTL_INJECT_RETVAL}"> "$EXP" -grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT" -match_diff "$OUT" "$EXP" + +for ret in 0 2 8 15 16; do + run_strace -a16 -e trace=ioctl \ + -e inject=ioctl:retval="${ret}":when="${IOCTL_INJECT_START}+" \ + ../ioctl_evdev-success \ + "${IOCTL_INJECT_START}" "${ret}"> "$EXP.${ret}" + grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT.$ret" + match_diff "$OUT.$ret" "$EXP.$ret" +done Index: strace-5.1/tests-mx32/ioctl_evdev-success-v.test =================================================================== --- strace-5.1.orig/tests-mx32/ioctl_evdev-success-v.test 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests-mx32/ioctl_evdev-success-v.test 2019-08-29 12:08:51.569168564 +0200 @@ -8,11 +8,14 @@ . "${srcdir=.}/scno_tampering.sh" : ${IOCTL_INJECT_START=256} -: ${IOCTL_INJECT_RETVAL=8} run_prog -run_strace -a16 -v -e trace=ioctl \ - -e inject=ioctl:retval="${IOCTL_INJECT_RETVAL}":when="${IOCTL_INJECT_START}+" \ - ../ioctl_evdev-success-v "${IOCTL_INJECT_START}" "${IOCTL_INJECT_RETVAL}"> "$EXP" -grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT" -match_diff "$OUT" "$EXP" + +for ret in 0 2 8 15 16; do + run_strace -a16 -v -e trace=ioctl \ + -e inject=ioctl:retval="${ret}":when="${IOCTL_INJECT_START}+" \ + ../ioctl_evdev-success-v \ + "${IOCTL_INJECT_START}" "${ret}"> "$EXP.$ret" + grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT.$ret" + match_diff "$OUT.$ret" "$EXP.$ret" +done Index: strace-5.1/tests-mx32/ioctl_evdev-success.test =================================================================== --- strace-5.1.orig/tests-mx32/ioctl_evdev-success.test 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests-mx32/ioctl_evdev-success.test 2019-08-29 12:08:51.569168564 +0200 @@ -8,11 +8,14 @@ . "${srcdir=.}/scno_tampering.sh" : ${IOCTL_INJECT_START=256} -: ${IOCTL_INJECT_RETVAL=8} run_prog -run_strace -a16 -e trace=ioctl \ - -e inject=ioctl:retval="${IOCTL_INJECT_RETVAL}":when="${IOCTL_INJECT_START}+" \ - ../ioctl_evdev-success "${IOCTL_INJECT_START}" "${IOCTL_INJECT_RETVAL}"> "$EXP" -grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT" -match_diff "$OUT" "$EXP" + +for ret in 0 2 8 15 16; do + run_strace -a16 -e trace=ioctl \ + -e inject=ioctl:retval="${ret}":when="${IOCTL_INJECT_START}+" \ + ../ioctl_evdev-success \ + "${IOCTL_INJECT_START}" "${ret}"> "$EXP.${ret}" + grep -v '^ioctl([012][,<]' < "$LOG" > "$OUT.$ret" + match_diff "$OUT.$ret" "$EXP.$ret" +done Index: strace-5.1/tests-m32/ioctl_evdev-success.c =================================================================== --- strace-5.1.orig/tests-m32/ioctl_evdev-success.c 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests-m32/ioctl_evdev-success.c 2019-08-29 12:09:27.898700830 +0200 @@ -9,6 +9,7 @@ #ifdef HAVE_LINUX_INPUT_H +# include # include # include # include @@ -16,17 +17,19 @@ # include # include "print_fields.h" +# define NUM_WORDS 4 + static const char *errstr; struct evdev_check { unsigned long cmd; const char *cmd_str; - void *arg_ptr; - void (*print_arg)(long rc, void *ptr, void *arg); + const void *arg_ptr; + void (*print_arg)(long rc, const void *ptr, const void *arg); }; static long -invoke_test_syscall(unsigned long cmd, void *p) +invoke_test_syscall(unsigned long cmd, const void *p) { long rc = ioctl(-1, cmd, p); errstr = sprintrc(rc); @@ -38,7 +41,7 @@ } static void -test_evdev(struct evdev_check *check, void *arg) +test_evdev(struct evdev_check *check, const void *arg) { long rc = invoke_test_syscall(check->cmd, check->arg_ptr); printf("ioctl(-1, %s, ", check->cmd_str); @@ -50,9 +53,9 @@ } static void -print_input_absinfo(long rc, void *ptr, void *arg) +print_input_absinfo(long rc, const void *ptr, const void *arg) { - struct input_absinfo *absinfo = ptr; + const struct input_absinfo *absinfo = ptr; if (rc < 0) { printf("%p", absinfo); @@ -74,9 +77,9 @@ } static void -print_input_id(long rc, void *ptr, void *arg) +print_input_id(long rc, const void *ptr, const void *arg) { - struct input_id *id = ptr; + const struct input_id *id = ptr; if (rc < 0) { printf("%p", id); @@ -91,10 +94,10 @@ # ifdef EVIOCGMTSLOTS static void -print_mtslots(long rc, void *ptr, void *arg) +print_mtslots(long rc, const void *ptr, const void *arg) { - int *buffer = ptr; - const char **str = arg; + const int *buffer = ptr; + const char * const * str = arg; int num = atoi(*(str + 1)); if (rc < 0) { @@ -111,27 +114,26 @@ # endif static void -print_getbit(long rc, void *ptr, void *arg) +print_getbit(long rc, const void *ptr, const void *arg) { - const char **str = arg; - int num = atoi(*str); + const char * const *str = arg; - if (rc < 0) { + if (rc <= 0) { printf("%p", ptr); return; } printf("["); - printf("%s", *(str + 1)); - for (unsigned int i = 2; i <= (unsigned) num; i++) { + for (unsigned long i = 0; str[i]; i++) { # if ! VERBOSE - if (i > 4) { + if (i >= 4) { printf(", ..."); break; } # endif - printf(", "); - printf("%s", *(str + i)); + if (i) + printf(", "); + printf("%s", str[i]); } printf("]"); } @@ -177,6 +179,7 @@ TAIL_ALLOC_OBJECT_CONST_PTR(struct input_id, id); TAIL_ALLOC_OBJECT_CONST_PTR(struct input_absinfo, absinfo); TAIL_ALLOC_OBJECT_CONST_PTR(int, bad_addr_slot); + # ifdef EVIOCGMTSLOTS int mtslots[] = { ABS_MT_SLOT, 1, 3 }; /* we use the second element to indicate the number of values */ @@ -190,36 +193,65 @@ const char *invalid_mtslot_str[] = { invalid_str, "1", "1" }; # endif + enum { ULONG_BIT = sizeof(unsigned long) * 8 }; + /* set more than 4 bits */ - unsigned long ev_more[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED | 1 << EV_SND | 1 << EV_PWR }; - /* we use the first element to indicate the number of set bits */ - /* ev_more_str[0] is "5" so the number of set bits is 5 */ - const char *ev_more_str[] = { "5", "EV_ABS", "EV_MSC", "EV_LED", "EV_SND", "EV_PWR" }; + static const unsigned long ev_more[NUM_WORDS] = { + 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED | 1 << EV_SND + | 1 << EV_PWR }; + static const char * const ev_more_str_2[] = { + "EV_ABS", "EV_MSC", NULL }; + static const char * const ev_more_str_3[] = { + "EV_ABS", "EV_MSC", "EV_LED", "EV_SND", "EV_PWR", NULL }; /* set less than 4 bits */ - unsigned long ev_less[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED }; - const char *ev_less_str[] = { "3", "EV_ABS", "EV_MSC", "EV_LED" }; + static const unsigned long ev_less[NUM_WORDS] = { + 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED }; + static const char * const ev_less_str_2[] = { + "EV_ABS", "EV_MSC", NULL }; + static const char * const ev_less_str_3[] = { + "EV_ABS", "EV_MSC", "EV_LED", NULL }; /* set zero bit */ - unsigned long ev_zero[] = { 0x0 }; - const char *ev_zero_str[] = { "0", " 0 " }; + static const unsigned long ev_zero[NUM_WORDS] = { 0x0 }; + static const char * const ev_zero_str[] = { " 0 ", NULL }; /* KEY_MAX is 0x2ff which is greater than retval * 8 */ - unsigned long key[] = { 1 << KEY_1 | 1 << KEY_2, 0 }; - const char *key_str[] = { "2", "KEY_1", "KEY_2" }; + static const unsigned long key[NUM_WORDS] = { + 1 << KEY_1 | 1 << KEY_2, + [ KEY_F12 / ULONG_BIT ] = 1 << (KEY_F12 % ULONG_BIT) }; + + static const char * const key_str_8[] = { + "KEY_1", "KEY_2", NULL }; + static const char * const key_str_16[] = { + "KEY_1", "KEY_2", "KEY_F12", NULL }; + + assert(sizeof(ev_more) >= (unsigned long) inject_retval); + assert(sizeof(ev_less) >= (unsigned long) inject_retval); + assert(sizeof(ev_zero) >= (unsigned long) inject_retval); + assert(sizeof(key) >= (unsigned long) inject_retval); struct { struct evdev_check check; - void *ptr; + const void *ptr; } a[] = { { { ARG_STR(EVIOCGID), id, print_input_id }, NULL }, { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo }, NULL }, { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL }, { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL }, - { { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit }, &ev_more_str }, - { { ARG_STR(EVIOCGBIT(0, 0)), ev_less, print_getbit }, &ev_less_str }, + { { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit }, + inject_retval * 8 <= EV_LED + ? (const void *) &ev_more_str_2 + : (const void *) &ev_more_str_3 }, + { { ARG_STR(EVIOCGBIT(0, 0)), ev_less, print_getbit }, + inject_retval * 8 <= EV_LED + ? (const void *) &ev_less_str_2 + : (const void *) &ev_less_str_3 }, { { ARG_STR(EVIOCGBIT(0, 0)), ev_zero, print_getbit }, &ev_zero_str }, - { { ARG_STR(EVIOCGBIT(EV_KEY, 0)), key, print_getbit }, &key_str}, + { { ARG_STR(EVIOCGBIT(EV_KEY, 0)), key, print_getbit }, + inject_retval * 8 <= KEY_F12 + ? (const void *) &key_str_8 + : (const void *) &key_str_16 }, # ifdef EVIOCGMTSLOTS { { ARG_STR(EVIOCGMTSLOTS(12)), mtslots, print_mtslots }, &mtslots_str }, { { ARG_STR(EVIOCGMTSLOTS(8)), invalid_mtslot, print_mtslots }, &invalid_mtslot_str } Index: strace-5.1/tests-mx32/ioctl_evdev-success.c =================================================================== --- strace-5.1.orig/tests-mx32/ioctl_evdev-success.c 2018-12-25 00:46:43.000000000 +0100 +++ strace-5.1/tests-mx32/ioctl_evdev-success.c 2019-08-29 12:09:30.350669261 +0200 @@ -9,6 +9,7 @@ #ifdef HAVE_LINUX_INPUT_H +# include # include # include # include @@ -16,17 +17,19 @@ # include # include "print_fields.h" +# define NUM_WORDS 4 + static const char *errstr; struct evdev_check { unsigned long cmd; const char *cmd_str; - void *arg_ptr; - void (*print_arg)(long rc, void *ptr, void *arg); + const void *arg_ptr; + void (*print_arg)(long rc, const void *ptr, const void *arg); }; static long -invoke_test_syscall(unsigned long cmd, void *p) +invoke_test_syscall(unsigned long cmd, const void *p) { long rc = ioctl(-1, cmd, p); errstr = sprintrc(rc); @@ -38,7 +41,7 @@ } static void -test_evdev(struct evdev_check *check, void *arg) +test_evdev(struct evdev_check *check, const void *arg) { long rc = invoke_test_syscall(check->cmd, check->arg_ptr); printf("ioctl(-1, %s, ", check->cmd_str); @@ -50,9 +53,9 @@ } static void -print_input_absinfo(long rc, void *ptr, void *arg) +print_input_absinfo(long rc, const void *ptr, const void *arg) { - struct input_absinfo *absinfo = ptr; + const struct input_absinfo *absinfo = ptr; if (rc < 0) { printf("%p", absinfo); @@ -74,9 +77,9 @@ } static void -print_input_id(long rc, void *ptr, void *arg) +print_input_id(long rc, const void *ptr, const void *arg) { - struct input_id *id = ptr; + const struct input_id *id = ptr; if (rc < 0) { printf("%p", id); @@ -91,10 +94,10 @@ # ifdef EVIOCGMTSLOTS static void -print_mtslots(long rc, void *ptr, void *arg) +print_mtslots(long rc, const void *ptr, const void *arg) { - int *buffer = ptr; - const char **str = arg; + const int *buffer = ptr; + const char * const * str = arg; int num = atoi(*(str + 1)); if (rc < 0) { @@ -111,27 +114,26 @@ # endif static void -print_getbit(long rc, void *ptr, void *arg) +print_getbit(long rc, const void *ptr, const void *arg) { - const char **str = arg; - int num = atoi(*str); + const char * const *str = arg; - if (rc < 0) { + if (rc <= 0) { printf("%p", ptr); return; } printf("["); - printf("%s", *(str + 1)); - for (unsigned int i = 2; i <= (unsigned) num; i++) { + for (unsigned long i = 0; str[i]; i++) { # if ! VERBOSE - if (i > 4) { + if (i >= 4) { printf(", ..."); break; } # endif - printf(", "); - printf("%s", *(str + i)); + if (i) + printf(", "); + printf("%s", str[i]); } printf("]"); } @@ -177,6 +179,7 @@ TAIL_ALLOC_OBJECT_CONST_PTR(struct input_id, id); TAIL_ALLOC_OBJECT_CONST_PTR(struct input_absinfo, absinfo); TAIL_ALLOC_OBJECT_CONST_PTR(int, bad_addr_slot); + # ifdef EVIOCGMTSLOTS int mtslots[] = { ABS_MT_SLOT, 1, 3 }; /* we use the second element to indicate the number of values */ @@ -190,36 +193,65 @@ const char *invalid_mtslot_str[] = { invalid_str, "1", "1" }; # endif + enum { ULONG_BIT = sizeof(unsigned long) * 8 }; + /* set more than 4 bits */ - unsigned long ev_more[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED | 1 << EV_SND | 1 << EV_PWR }; - /* we use the first element to indicate the number of set bits */ - /* ev_more_str[0] is "5" so the number of set bits is 5 */ - const char *ev_more_str[] = { "5", "EV_ABS", "EV_MSC", "EV_LED", "EV_SND", "EV_PWR" }; + static const unsigned long ev_more[NUM_WORDS] = { + 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED | 1 << EV_SND + | 1 << EV_PWR }; + static const char * const ev_more_str_2[] = { + "EV_ABS", "EV_MSC", NULL }; + static const char * const ev_more_str_3[] = { + "EV_ABS", "EV_MSC", "EV_LED", "EV_SND", "EV_PWR", NULL }; /* set less than 4 bits */ - unsigned long ev_less[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED }; - const char *ev_less_str[] = { "3", "EV_ABS", "EV_MSC", "EV_LED" }; + static const unsigned long ev_less[NUM_WORDS] = { + 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED }; + static const char * const ev_less_str_2[] = { + "EV_ABS", "EV_MSC", NULL }; + static const char * const ev_less_str_3[] = { + "EV_ABS", "EV_MSC", "EV_LED", NULL }; /* set zero bit */ - unsigned long ev_zero[] = { 0x0 }; - const char *ev_zero_str[] = { "0", " 0 " }; + static const unsigned long ev_zero[NUM_WORDS] = { 0x0 }; + static const char * const ev_zero_str[] = { " 0 ", NULL }; /* KEY_MAX is 0x2ff which is greater than retval * 8 */ - unsigned long key[] = { 1 << KEY_1 | 1 << KEY_2, 0 }; - const char *key_str[] = { "2", "KEY_1", "KEY_2" }; + static const unsigned long key[NUM_WORDS] = { + 1 << KEY_1 | 1 << KEY_2, + [ KEY_F12 / ULONG_BIT ] = 1 << (KEY_F12 % ULONG_BIT) }; + + static const char * const key_str_8[] = { + "KEY_1", "KEY_2", NULL }; + static const char * const key_str_16[] = { + "KEY_1", "KEY_2", "KEY_F12", NULL }; + + assert(sizeof(ev_more) >= (unsigned long) inject_retval); + assert(sizeof(ev_less) >= (unsigned long) inject_retval); + assert(sizeof(ev_zero) >= (unsigned long) inject_retval); + assert(sizeof(key) >= (unsigned long) inject_retval); struct { struct evdev_check check; - void *ptr; + const void *ptr; } a[] = { { { ARG_STR(EVIOCGID), id, print_input_id }, NULL }, { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo }, NULL }, { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL }, { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL }, - { { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit }, &ev_more_str }, - { { ARG_STR(EVIOCGBIT(0, 0)), ev_less, print_getbit }, &ev_less_str }, + { { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit }, + inject_retval * 8 <= EV_LED + ? (const void *) &ev_more_str_2 + : (const void *) &ev_more_str_3 }, + { { ARG_STR(EVIOCGBIT(0, 0)), ev_less, print_getbit }, + inject_retval * 8 <= EV_LED + ? (const void *) &ev_less_str_2 + : (const void *) &ev_less_str_3 }, { { ARG_STR(EVIOCGBIT(0, 0)), ev_zero, print_getbit }, &ev_zero_str }, - { { ARG_STR(EVIOCGBIT(EV_KEY, 0)), key, print_getbit }, &key_str}, + { { ARG_STR(EVIOCGBIT(EV_KEY, 0)), key, print_getbit }, + inject_retval * 8 <= KEY_F12 + ? (const void *) &key_str_8 + : (const void *) &key_str_16 }, # ifdef EVIOCGMTSLOTS { { ARG_STR(EVIOCGMTSLOTS(12)), mtslots, print_mtslots }, &mtslots_str }, { { ARG_STR(EVIOCGMTSLOTS(8)), invalid_mtslot, print_mtslots }, &invalid_mtslot_str }