diff options
-rw-r--r-- | tests/.gitignore | 8 | ||||
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/gen_tests.in | 8 | ||||
-rw-r--r-- | tests/ioctl_lirc-Xabbrev.c | 2 | ||||
-rw-r--r-- | tests/ioctl_lirc-Xraw.c | 2 | ||||
-rw-r--r-- | tests/ioctl_lirc-Xverbose.c | 2 | ||||
-rw-r--r-- | tests/ioctl_lirc-success-Xabbrev.c | 2 | ||||
-rw-r--r-- | tests/ioctl_lirc-success-Xraw.c | 2 | ||||
-rw-r--r-- | tests/ioctl_lirc-success-Xverbose.c | 2 | ||||
-rw-r--r-- | tests/ioctl_lirc-success.c | 2 | ||||
-rw-r--r-- | tests/ioctl_lirc.c | 487 | ||||
-rwxr-xr-x | tests/pure_executables.list | 4 |
12 files changed, 525 insertions, 0 deletions
diff --git a/tests/.gitignore b/tests/.gitignore index 128d9a076..c86a25e7f 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -325,6 +325,14 @@ ioctl_kd-success-s1024-Xverbose ioctl_kvm_run ioctl_kvm_run-v ioctl_kvm_run_auxstr_vcpu +ioctl_lirc +ioctl_lirc-Xabbrev +ioctl_lirc-Xraw +ioctl_lirc-Xverbose +ioctl_lirc-success +ioctl_lirc-success-Xabbrev +ioctl_lirc-success-Xraw +ioctl_lirc-success-Xverbose ioctl_loop ioctl_loop-nv ioctl_loop-v diff --git a/tests/Makefile.am b/tests/Makefile.am index 9623e672d..a086839b6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -200,6 +200,10 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ ioctl_kd-success-s1024-Xabbrev \ ioctl_kd-success-s1024-Xraw \ ioctl_kd-success-s1024-Xverbose \ + ioctl_lirc-success \ + ioctl_lirc-success-Xabbrev \ + ioctl_lirc-success-Xraw \ + ioctl_lirc-success-Xverbose \ ioctl_loop-nv \ ioctl_loop-v \ ioctl_mtd-success \ diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 4b16f9bff..902bccf7a 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -339,6 +339,14 @@ ioctl_kd-success-s1024-Xverbose +ioctl-success.sh -a20 -s1024 -Xverbose ioctl_kvm_run +ioctl.test -a36 -y ioctl_kvm_run-v +ioctl.test -v -a36 -y ioctl_kvm_run_auxstr_vcpu +ioctl.test -a36 -y -e kvm=vcpu +ioctl_lirc +ioctl.test -a22 +ioctl_lirc-Xabbrev +ioctl.test -Xabbrev -a22 +ioctl_lirc-Xraw +ioctl.test -Xraw -a21 +ioctl_lirc-Xverbose +ioctl.test -Xverbose -a39 +ioctl_lirc-success +ioctl-success.sh -a22 +ioctl_lirc-success-Xabbrev +ioctl-success.sh -a22 -Xabbrev +ioctl_lirc-success-Xraw +ioctl-success.sh -a21 -Xraw +ioctl_lirc-success-Xverbose +ioctl-success.sh -a39 -Xverbose ioctl_loop +ioctl.test ioctl_loop-nv +ioctl.test -a22 -e verbose=none ioctl_loop-v +ioctl.test -v diff --git a/tests/ioctl_lirc-Xabbrev.c b/tests/ioctl_lirc-Xabbrev.c new file mode 100644 index 000000000..961f21cff --- /dev/null +++ b/tests/ioctl_lirc-Xabbrev.c @@ -0,0 +1,2 @@ +#define XLAT_ABBREV 1 +#include "ioctl_lirc.c" diff --git a/tests/ioctl_lirc-Xraw.c b/tests/ioctl_lirc-Xraw.c new file mode 100644 index 000000000..587b01512 --- /dev/null +++ b/tests/ioctl_lirc-Xraw.c @@ -0,0 +1,2 @@ +#define XLAT_RAW 1 +#include "ioctl_lirc.c" diff --git a/tests/ioctl_lirc-Xverbose.c b/tests/ioctl_lirc-Xverbose.c new file mode 100644 index 000000000..0cc80393c --- /dev/null +++ b/tests/ioctl_lirc-Xverbose.c @@ -0,0 +1,2 @@ +#define XLAT_VERBOSE 1 +#include "ioctl_lirc.c" diff --git a/tests/ioctl_lirc-success-Xabbrev.c b/tests/ioctl_lirc-success-Xabbrev.c new file mode 100644 index 000000000..1c3921677 --- /dev/null +++ b/tests/ioctl_lirc-success-Xabbrev.c @@ -0,0 +1,2 @@ +#define XLAT_ABBREV 1 +#include "ioctl_lirc-success.c" diff --git a/tests/ioctl_lirc-success-Xraw.c b/tests/ioctl_lirc-success-Xraw.c new file mode 100644 index 000000000..e7800a078 --- /dev/null +++ b/tests/ioctl_lirc-success-Xraw.c @@ -0,0 +1,2 @@ +#define XLAT_RAW 1 +#include "ioctl_lirc-success.c" diff --git a/tests/ioctl_lirc-success-Xverbose.c b/tests/ioctl_lirc-success-Xverbose.c new file mode 100644 index 000000000..069752334 --- /dev/null +++ b/tests/ioctl_lirc-success-Xverbose.c @@ -0,0 +1,2 @@ +#define XLAT_VERBOSE 1 +#include "ioctl_lirc-success.c" diff --git a/tests/ioctl_lirc-success.c b/tests/ioctl_lirc-success.c new file mode 100644 index 000000000..a918f833b --- /dev/null +++ b/tests/ioctl_lirc-success.c @@ -0,0 +1,2 @@ +#define INJECT_RETVAL 1 +#include "ioctl_lirc.c" diff --git a/tests/ioctl_lirc.c b/tests/ioctl_lirc.c new file mode 100644 index 000000000..3a3265df9 --- /dev/null +++ b/tests/ioctl_lirc.c @@ -0,0 +1,487 @@ +/* + * Check decoding of LIRC_* commands of the ioctl syscall. + * + * Copyright (c) 2022 Eugene Syromyatnikov <evgsyr@gmail.com>. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" + +#include "scno.h" + +#include <errno.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <linux/ioctl.h> +#include <linux/lirc.h> + +#ifndef INJECT_RETVAL +# define INJECT_RETVAL 0 +#endif + +#if INJECT_RETVAL +# define INJ_STR " (INJECTED)" +#else +# define INJ_STR "" +#endif + +/* A hack for handling different types of _IOC() on various platforms */ +#if XLAT_RAW +# define XLAT_ARGS_U(a_) (unsigned int) (a_) +#elif XLAT_VERBOSE +# define XLAT_ARGS_U(a_) (unsigned int) (a_), #a_ +#else +# define XLAT_ARGS_U(a_) #a_ +#endif + +static const char *errstr; + +static long +sys_ioctl(kernel_long_t fd, kernel_ulong_t cmd, kernel_ulong_t arg) +{ + const long rc = syscall(__NR_ioctl, fd, cmd, arg); + errstr = sprintrc(rc); + return rc; +} + +int +main(int argc, char **argv) +{ + static const struct { + uint32_t val; + const char *str; + } dirs[] = { + { ARG_STR(_IOC_NONE) }, + { ARG_STR(_IOC_READ) }, + { ARG_STR(_IOC_WRITE) }, + { ARG_STR(_IOC_READ|_IOC_WRITE) }, + }; + + TAIL_ALLOC_OBJECT_CONST_PTR(uint32_t, value); + *value = 0xbeefcafe; + + + /* + * Start of output marker. printf is in front of ioctl() here because + * musl calls an ioctl before the first output to stdout, specifically, + * ioctl(TIOCGWINSZ) in src/stdio/__stdout_write.c:__stdout_write. + */ + errno = EBADF; + printf("ioctl(-1, " XLAT_FMT ", NULL) = -1 EBADF (%m)\n", + XLAT_ARGS_U(LIRC_GET_FEATURES)); + fflush(NULL); + sys_ioctl(-1, LIRC_GET_FEATURES, 0); + + +#if INJECT_RETVAL + if (argc == 1) + return 0; + + if (argc < 3) + error_msg_and_fail("Usage: %s NUM_SKIP INJECT_RETVAL", argv[0]); + + unsigned long num_skip = strtoul(argv[1], NULL, 0); + long inject_retval = strtol(argv[2], NULL, 0); + bool locked = false; + long rc; + + if (inject_retval < 0) + error_msg_and_fail("Expected non-negative INJECT_RETVAL, " + "but got %ld", inject_retval); + + for (unsigned long i = 0; i < num_skip; i++) { + rc = sys_ioctl(-1, LIRC_GET_FEATURES, 0); + printf("ioctl(-1, " XLAT_FMT ", NULL) = %s%s\n", + XLAT_ARGS_U(LIRC_GET_FEATURES), + errstr, rc == inject_retval ? " (INJECTED)" : ""); + + if (rc != inject_retval) + continue; + + locked = true; + break; + } + + if (!locked) { + error_msg_and_fail("Have not locked on ioctl(-1" + ", SECCOMP_IOCTL_NOTIF_RECV, NULL) " + "returning %lu", inject_retval); + } +#endif /* INJECT_RETVAL */ + + + /* Unknown lirc ioctl */ +#define C(dir_, nr_, size_) _IOC((dir_), 'i', (nr_), (size_)) +#define L SIZEOF_LONG +#define __ (_IOC_NONE) +#define R_ (_IOC_READ) +#define _W (_IOC_WRITE) +#define RW (_IOC_READ|_IOC_WRITE) + static const struct { + unsigned int cmd; + bool skip; /**< Skip IOCs that are decoded by strace */ + const char *name; + } named_ioctls[] = { + { C(__, 0, 0), 0, "I915_PERF_IOCTL_ENABLE" }, + { C(__, 1, 0), 0, "I915_PERF_IOCTL_DISABLE" }, + { C(__, 2, 0), 0, "I915_PERF_IOCTL_CONFIG" }, + + { C(R_, 14, 2), 0, "IPMICTL_REGISTER_FOR_CMD" }, + { C(R_, 15, 2), 0, "IPMICTL_UNREGISTER_FOR_CMD" }, + + { C(R_, 0, 4), 1, "LIRC_GET_FEATURES" }, + { C(R_, 1, 4), 1, "LIRC_GET_SEND_MODE" }, + { C(R_, 2, 4), 1, "LIRC_GET_REC_MODE" }, + { C(R_, 7, 4), 1, "LIRC_GET_REC_RESOLUTION" }, + { C(R_, 8, 4), 1, "I2OVALIDATE or LIRC_GET_MIN_TIMEOUT" }, + { C(R_, 9, 4), 1, "LIRC_GET_MAX_TIMEOUT" }, + { C(R_, 15, 4), 1, "LIRC_GET_LENGTH" }, + { C(R_, 16, 4), 0, "IPMICTL_SET_GETS_EVENTS_CMD" }, + { C(R_, 17, 4), 0, "IPMICTL_SET_MY_ADDRESS_CMD" }, + { C(R_, 18, 4), 0, "IPMICTL_GET_MY_ADDRESS_CMD" }, + { C(R_, 19, 4), 0, "IPMICTL_SET_MY_LUN_CMD" }, + { C(R_, 20, 4), 0, "IPMICTL_GET_MY_LUN_CMD" }, + { C(R_, 24, 4), 0, "IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD" }, + { C(R_, 25, 4), 0, "IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD" }, + { C(R_, 26, 4), 0, "IPMICTL_SET_MY_CHANNEL_LUN_CMD" }, + { C(R_, 27, 4), 0, "IPMICTL_GET_MY_CHANNEL_LUN_CMD" }, + { C(R_, 30, 4), 0, "IPMICTL_GET_MAINTENANCE_MODE_CMD" }, + { C(R_, 36, 4), 1, "LIRC_GET_REC_TIMEOUT" }, + { C(R_, 128, 4), 0, "I8K_BIOS_VERSION" }, + { C(R_, 129, 4), 0, "I8K_MACHINE_ID" }, +#if SIZEOF_LONG == 4 + { C(R_, 130, 4), 0, "I8K_POWER_STATUS" }, + { C(R_, 131, 4), 0, "I8K_FN_STATUS" }, + { C(R_, 132, 4), 0, "I8K_GET_TEMP" }, +#endif + { C(R_, 144, 4), 0, "IIO_GET_EVENT_FD_IOCTL" }, + + { C(R_, 12, 8), 0, "I2OPASSTHRU32" }, + { C(R_, 22, 8), 0, "IPMICTL_SET_TIMING_PARMS_CMD" }, + { C(R_, 23, 8), 0, "IPMICTL_GET_TIMING_PARMS_CMD" }, +#if SIZEOF_LONG == 8 + { C(R_, 130, 8), 0, "I8K_POWER_STATUS" }, + { C(R_, 131, 8), 0, "I8K_FN_STATUS" }, + { C(R_, 132, 8), 0, "I8K_GET_TEMP" }, +#endif + + { C(R_, 28, 12), 0, "IPMICTL_REGISTER_FOR_CMD_CHANS" }, + { C(R_, 29, 12), 0, "IPMICTL_UNREGISTER_FOR_CMD_CHANS" }, + +#if SIZEOF_LONG == 8 + { C(R_, 12, 16), 0, "I2OPASSTHRU" }, +#endif + +#if SIZEOF_LONG == 4 + { C(R_, 13, 20), 0, "IPMICTL_SEND_COMMAND" }, + + { C(R_, 21, 28), 0, "IPMICTL_SEND_COMMAND_SETTIME" }, +#endif + + { C(R_, 0, 32), 0, "I2OGETIOPS" }, + +#if SIZEOF_LONG == 8 + { C(R_, 13, 40), 0, "IPMICTL_SEND_COMMAND" }, + + { C(R_, 21, 48), 0, "IPMICTL_SEND_COMMAND_SETTIME" }, +#endif + + { C(_W, 17, 4), 1, "LIRC_SET_SEND_MODE" }, + { C(_W, 18, 4), 1, "LIRC_SET_REC_MODE" }, + { C(_W, 19, 4), 1, "LIRC_SET_SEND_CARRIER" }, + { C(_W, 20, 4), 1, "LIRC_SET_REC_CARRIER" }, + { C(_W, 21, 4), 1, "LIRC_SET_SEND_DUTY_CYCLE" }, + { C(_W, 23, 4), 1, "LIRC_SET_TRANSMITTER_MASK" }, + { C(_W, 24, 4), 1, "LIRC_SET_REC_TIMEOUT" }, + { C(_W, 25, 4), 1, "LIRC_SET_REC_TIMEOUT_REPORTS" }, + { C(_W, 29, 4), 1, "LIRC_SET_MEASURE_CARRIER_MODE" }, + { C(_W, 31, 4), 1, "IPMICTL_SET_MAINTENANCE_MODE_CMD or " + "LIRC_SET_MEASURE_CARRIER_MODE" }, + { C(_W, 35, 4), 1, "LIRC_SET_WIDEBAND_RECEIVER" }, + + { C(_W, 10, 12), 0, "I2OEVTREG" }, + +#if SIZEOF_LONG == 4 + { C(RW, 133, 4), 0, "I8K_GET_SPEED" }, + { C(RW, 134, 4), 0, "I8K_GET_FAN" }, + { C(RW, 135, 4), 0, "I8K_SET_FAN" }, +#endif + { C(RW, 145, 4), 0, "IIO_BUFFER_GET_FD_IOCTL" }, + +#if SIZEOF_LONG == 8 + { C(RW, 133, 8), 0, "I8K_GET_SPEED" }, + { C(RW, 134, 8), 0, "I8K_GET_FAN" }, + { C(RW, 135, 8), 0, "I8K_SET_FAN" }, +#endif + + { C(RW, 1, L*3), 0, "I2OHRTGET" }, + { C(RW, 2, L*3), 0, "I2OLCTGET" }, + + { C(RW, 3, 8+L*4), 0, "I2OPARMSET" }, + { C(RW, 4, 8+L*4), 0, "I2OPARMGET" }, +#if SIZEOF_LONG == 4 + { C(RW, 11, 24), 0, "IPMICTL_RECEIVE_MSG_TRUNC" }, + { C(RW, 12, 24), 0, "IPMICTL_RECEIVE_MSG" }, +#endif + +#if defined(__m68k__) + { C(RW, 5, 26), 0, "I2OSWDL" }, + { C(RW, 6, 26), 0, "I2OSWUL" }, + { C(RW, 7, 26), 0, "I2OSWDEL" }, + { C(RW, 9, 26), 0, "I2OHTML" }, +#else + { C(RW, 5, 8+L*5), 0, "I2OSWDL" }, + { C(RW, 6, 8+L*5), 0, "I2OSWUL" }, + { C(RW, 7, 8+L*5), 0, "I2OSWDEL" }, + { C(RW, 9, 8+L*5), 0, "I2OHTML" }, +#endif +#if SIZEOF_LONG == 8 + { C(RW, 11, 48), 0, "IPMICTL_RECEIVE_MSG_TRUNC" }, + { C(RW, 12, 48), 0, "IPMICTL_RECEIVE_MSG" }, +#endif + }; +#undef C +#undef L +#undef __ +#undef R_ +#undef _W +#undef RW + + size_t pos = 0; + + static const char dummy[64] = "OH HAI THAR! 01234567890" + "01234567890123456789" + "01234567890123456789"; + + for (size_t i = 0; i < ARRAY_SIZE(dirs); i++) { + for (unsigned int j = 0; j <= 64; j += 2) { + for (unsigned int k = 0; k <= 255; k++) { + const unsigned int ioc = _IOC(dirs[i].val, 'i', + k, j); +#if !XLAT_RAW + char ioc_buf[256]; + const char *ioc_str; +#endif + + if (pos < ARRAY_SIZE(named_ioctls) + && ioc == named_ioctls[pos].cmd) { +#if !XLAT_RAW + ioc_str = named_ioctls[pos].name; +#endif + if (named_ioctls[pos++].skip) + continue; + } +#if !XLAT_RAW + else { + snprintf(ioc_buf, sizeof(ioc_buf), + "_IOC(%s, 0x69, %#x, %#x)", + dirs[i].str, k, j); + ioc_str = ioc_buf; + } +#endif + + sys_ioctl(-1, ioc, 0); + printf("ioctl(-1, " XLAT_KNOWN_FMT("%#x", "%s") + ", 0) = %s" INJ_STR "\n", + XLAT_SEL(ioc, ioc_str), errstr); + + sys_ioctl(-1, ioc, (uintptr_t) dummy); + printf("ioctl(-1, " XLAT_KNOWN_FMT("%#x", "%s") + ", %#lx) = %s" INJ_STR "\n", + XLAT_SEL(ioc, ioc_str), + (unsigned long) (uintptr_t) dummy, + errstr); + } + } + } + + + /* LIRC_GET_FEATURES */ + static const struct strval32 features_vals[] = { + { ARG_STR(0) }, + { ARG_XLAT_KNOWN(0x1, "LIRC_CAN_SEND_RAW") }, + { ARG_XLAT_KNOWN(0xa1fac0de, + "LIRC_CAN_SEND_PULSE" + "|LIRC_CAN_SEND_MODE2" + "|LIRC_CAN_SEND_SCANCODE" + "|LIRC_CAN_SEND_LIRCCODE" + "|LIRC_CAN_REC_PULSE" + "|LIRC_CAN_REC_SCANCODE" + "|LIRC_CAN_REC_LIRCCODE" + "|LIRC_CAN_SET_REC_CARRIER" + "|LIRC_CAN_GET_REC_RESOLUTION" + "|LIRC_CAN_SET_REC_CARRIER_RANGE" + "|0xe0c0c0") }, + { ARG_XLAT_KNOWN(0xdeadbeef, + "LIRC_CAN_SEND_RAW" + "|LIRC_CAN_SEND_PULSE" + "|LIRC_CAN_SEND_MODE2" + "|LIRC_CAN_SEND_SCANCODE" + "|LIRC_CAN_SET_SEND_DUTY_CYCLE" + "|LIRC_CAN_SET_TRANSMITTER_MASK" + "|LIRC_CAN_REC_RAW" + "|LIRC_CAN_REC_MODE2" + "|LIRC_CAN_REC_SCANCODE" + "|LIRC_CAN_MEASURE_CARRIER" + "|LIRC_CAN_USE_WIDEBAND_RECEIVER" + "|LIRC_CAN_SET_REC_FILTER" + "|LIRC_CAN_SET_REC_TIMEOUT" + "|LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE" + "|LIRC_CAN_SET_REC_CARRIER_RANGE" + "|0xa0b8e0") }, + { ARG_XLAT_UNKNOWN(0xe0f8e0, "LIRC_CAN_???") }, + }; + TAIL_ALLOC_OBJECT_CONST_PTR(uint32_t, features); + + sys_ioctl(-1, LIRC_GET_FEATURES, 0); + printf("ioctl(-1, " XLAT_FMT ", NULL) = %s" INJ_STR "\n", + XLAT_ARGS_U(LIRC_GET_FEATURES), errstr); + + sys_ioctl(-1, LIRC_GET_FEATURES, (uintptr_t) features + 1); + printf("ioctl(-1, " XLAT_FMT ", %#lx) = %s" INJ_STR "\n", + XLAT_ARGS_U(LIRC_GET_FEATURES), + (unsigned long) (uintptr_t) features + 1, errstr); + + for (size_t i = 0; i < ARRAY_SIZE(features_vals); i++) { + *features = features_vals[i].val; + sys_ioctl(-1, LIRC_GET_FEATURES, (uintptr_t) features); + printf("ioctl(-1, " XLAT_FMT ", " +#if INJECT_RETVAL + "[%s]" +#else + "%#lx" +#endif + ") = %s" INJ_STR "\n", + XLAT_ARGS_U(LIRC_GET_FEATURES), +#if INJECT_RETVAL + features_vals[i].str +#else + (unsigned long) (uintptr_t) features +#endif + , errstr); + } + + + /* LIRC_[SG]ET_{SEND,REC}_MODE */ + static const struct strval32 mode_cmds[] = { + { ARG_STR(LIRC_GET_SEND_MODE) }, + { ARG_STR(LIRC_GET_REC_MODE) }, + { ARG_STR(LIRC_SET_SEND_MODE) }, + { ARG_STR(LIRC_SET_REC_MODE) }, + }; + static const struct strval32 modes[] = { + { ARG_XLAT_UNKNOWN(0, "LIRC_MODE_???") }, + { ARG_XLAT_KNOWN(0x1, "LIRC_MODE_RAW") }, + { ARG_XLAT_KNOWN(0x2, "LIRC_MODE_PULSE") }, + { ARG_XLAT_UNKNOWN(0x3, "LIRC_MODE_???") }, + { ARG_XLAT_KNOWN(0x4, "LIRC_MODE_MODE2") }, + { ARG_XLAT_UNKNOWN(0x20, "LIRC_MODE_???") }, + { ARG_XLAT_UNKNOWN(0xdeadface, "LIRC_MODE_???") }, + }; + TAIL_ALLOC_OBJECT_CONST_PTR(uint32_t, mode); + + for (size_t i = 0; i < ARRAY_SIZE(mode_cmds); i++) { + for (size_t j = 0; j < ARRAY_SIZE(modes); j++) { + *mode = modes[j].val; + + sys_ioctl(-1, mode_cmds[i].val, 0); + printf("ioctl(-1, " XLAT_FMT ", NULL) = %s" INJ_STR + "\n", + XLAT_SEL(mode_cmds[i].val, mode_cmds[i].str), + errstr); + + sys_ioctl(-1, mode_cmds[i].val, (uintptr_t) mode + 4); + printf("ioctl(-1, " XLAT_FMT ", %#lx) = %s" INJ_STR + "\n", + XLAT_SEL(mode_cmds[i].val, mode_cmds[i].str), + (unsigned long) (uintptr_t) mode + 4, errstr); + + sys_ioctl(-1, mode_cmds[i].val, (uintptr_t) mode); + printf("ioctl(-1, " XLAT_FMT ", ", + XLAT_SEL(mode_cmds[i].val, mode_cmds[i].str)); + if (_IOC_DIR(mode_cmds[i].val) == _IOC_WRITE + || INJECT_RETVAL) { + printf("[%s]", modes[j].str); + } else { + printf("%p", mode); + } + printf(") = %s" INJ_STR "\n", errstr); + } + } + + + /* u32 cmds */ + static const struct strval32 u32_cmds[] = { + { ARG_STR(LIRC_GET_REC_RESOLUTION) }, + { LIRC_GET_MIN_TIMEOUT, "I2OVALIDATE or LIRC_GET_MIN_TIMEOUT" }, + { ARG_STR(LIRC_GET_MAX_TIMEOUT) }, + { ARG_STR(LIRC_GET_LENGTH) }, + { ARG_STR(LIRC_SET_SEND_CARRIER) }, + { ARG_STR(LIRC_SET_REC_CARRIER) }, + { ARG_STR(LIRC_SET_SEND_DUTY_CYCLE) }, + { ARG_STR(LIRC_SET_REC_TIMEOUT) }, + { LIRC_SET_REC_CARRIER_RANGE, + "IPMICTL_SET_MAINTENANCE_MODE_CMD or " + "LIRC_SET_REC_CARRIER_RANGE" }, + { ARG_STR(LIRC_GET_REC_TIMEOUT) }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(u32_cmds); i++) { + sys_ioctl(-1, u32_cmds[i].val, 0); + printf("ioctl(-1, " XLAT_FMT ", NULL) = %s" INJ_STR "\n", + XLAT_SEL(u32_cmds[i].val, u32_cmds[i].str), errstr); + + sys_ioctl(-1, u32_cmds[i].val, (uintptr_t) value + 4); + printf("ioctl(-1, " XLAT_FMT ", %#lx) = %s" INJ_STR "\n", + XLAT_SEL(u32_cmds[i].val, u32_cmds[i].str), + (unsigned long) (uintptr_t) value + 4, errstr); + + sys_ioctl(-1, u32_cmds[i].val, (uintptr_t) value); + printf("ioctl(-1, " XLAT_FMT ", ", + XLAT_SEL(u32_cmds[i].val, u32_cmds[i].str)); + if (_IOC_DIR(u32_cmds[i].val) == _IOC_WRITE || INJECT_RETVAL) + printf("[3203386110]"); + else + printf("%p", value); + printf(") = %s" INJ_STR "\n", errstr); + } + + + /* x32 cmds */ + static const struct strval32 x32_cmds[] = { + { ARG_STR(LIRC_SET_TRANSMITTER_MASK) }, + { ARG_STR(LIRC_SET_REC_TIMEOUT_REPORTS) }, + { ARG_STR(LIRC_SET_MEASURE_CARRIER_MODE) }, + { ARG_STR(LIRC_SET_WIDEBAND_RECEIVER) }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(x32_cmds); i++) { + sys_ioctl(-1, x32_cmds[i].val, 0); + printf("ioctl(-1, " XLAT_FMT ", NULL) = %s" INJ_STR "\n", + XLAT_SEL(x32_cmds[i].val, x32_cmds[i].str), errstr); + + sys_ioctl(-1, x32_cmds[i].val, (uintptr_t) value + 4); + printf("ioctl(-1, " XLAT_FMT ", %#lx) = %s" INJ_STR "\n", + XLAT_SEL(x32_cmds[i].val, x32_cmds[i].str), + (unsigned long) (uintptr_t) value + 4, errstr); + + sys_ioctl(-1, x32_cmds[i].val, (uintptr_t) value); + printf("ioctl(-1, " XLAT_FMT ", ", + XLAT_SEL(x32_cmds[i].val, x32_cmds[i].str)); + if (_IOC_DIR(x32_cmds[i].val) == _IOC_WRITE || INJECT_RETVAL) + printf("[0xbeefcafe]"); + else + printf("%p", value); + printf(") = %s" INJ_STR "\n", errstr); + } + + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 296e22359..9f8ec04eb 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -216,6 +216,10 @@ ioctl_kd-Xverbose ioctl_kvm_run ioctl_kvm_run-v ioctl_kvm_run_auxstr_vcpu +ioctl_lirc +ioctl_lirc-Xabbrev +ioctl_lirc-Xraw +ioctl_lirc-Xverbose ioctl_loop ioctl_mtd ioctl_nbd |