From ced129dcf654836850f475413120b3a3fd8de707 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sun, 4 Feb 2024 11:56:58 +0100 Subject: [PATCH] enosys: add support for alternative error codes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Weißschuh --- meson.build | 2 +- misc-utils/Makemodule.am | 2 +- misc-utils/enosys.1.adoc | 26 ++++++++++++++++++++-- misc-utils/enosys.c | 38 +++++++++++++++++++++++++++----- tests/expected/misc/enosys-basic | 2 ++ tests/expected/misc/enosys-ioctl | 2 ++ tests/ts/misc/enosys | 4 ++++ 7 files changed, 67 insertions(+), 9 deletions(-) diff --git a/meson.build b/meson.build index fbed1f79f..307c23654 100644 --- a/meson.build +++ b/meson.build @@ -3018,7 +3018,7 @@ syscalls_h = custom_target('syscalls.h', if cc.compiles(fs.read('include/audit-arch.h'), name : 'has AUDIT_ARCH_NATIVE') exe = executable( 'enosys', - 'misc-utils/enosys.c', syscalls_h, + 'misc-utils/enosys.c', syscalls_h, errnos_h, include_directories : includes, link_with : [lib_common], install_dir : usrbin_exec_dir, diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am index 7524056ed..514b27adc 100644 --- a/misc-utils/Makemodule.am +++ b/misc-utils/Makemodule.am @@ -330,7 +330,7 @@ endif if BUILD_ENOSYS -misc-utils/enosys.c: syscalls.h +misc-utils/enosys.c: syscalls.h errnos.h syscalls.h: $(top_srcdir)/tools/all_syscalls @echo ' GEN $@' diff --git a/misc-utils/enosys.1.adoc b/misc-utils/enosys.1.adoc index 71452e078..7eba7efff 100644 --- a/misc-utils/enosys.1.adoc +++ b/misc-utils/enosys.1.adoc @@ -25,10 +25,12 @@ syscalls as would happen when running on old kernels. == OPTIONS *-s*, *--syscall*:: -Syscall to block. Can be specified multiple times. +Syscall to block with *ENOSYS*. Can be specified multiple times. +An alternative error number or name can be specified with a colon. *-i*, *--ioctl*:: -Ioctl to block. Can be specified multiple times. +Ioctl to block with *ENOTTY*. Can be specified multiple times. +An alternative error number or name can be specified with a colon. *-l*, *--list*:: List syscalls known to *enosys*. @@ -43,6 +45,26 @@ The dump can for example be used by *setpriv --seccomp-filter*. include::man-common/help-version.adoc[] +== EXAMPLES + + # fail syscall "fallocate" with ENOSYS + enosys -s fallocate ... + + # fail syscall "fallocate" with ENOMEM + enosys -s fallocate:ENOMEM ... + + # fail syscall "fallocate" with value 12/ENOMEM + enosys -s fallocate:12 ... + + # fail ioctl FIOCLEX with ENOTTY + enosys -i FIOCLEX ... + + # fail ioctl FIOCLEX with ENOMEM + enosys -i FIOCLEX:ENOMEM ... + + # fail ioctl FIOCLEX with value 12/ENOMEM + enosys -i FIOCLEX:12 ... + == EXIT STATUS *enosys* exits with the status code of the executed process. diff --git a/misc-utils/enosys.c b/misc-utils/enosys.c index d9328f1c7..dc120cd83 100644 --- a/misc-utils/enosys.c +++ b/misc-utils/enosys.c @@ -63,6 +63,12 @@ static const struct syscall syscalls[] = { #undef UL_SYSCALL }; +static const struct syscall errnos[] = { +#define UL_ERRNO(name, nr) { name, nr }, +#include "errnos.h" +#undef UL_ERRNO +}; + static const struct syscall ioctls[] = { { "FIOCLEX", FIOCLEX }, }; @@ -94,24 +100,46 @@ struct blocked_number { int ret; }; -static struct blocked_number *parse_block(const char *s, int ret, const struct syscall syscalls[], size_t nsyscalls) +static struct blocked_number *parse_block(const char *s, int ret, const struct syscall entities[], size_t n_entities) { struct blocked_number *blocked; + const char *name, *error_name; long blocked_number; + char *colon; bool found; size_t i; + colon = strchr(s, ':'); + if (colon) { + name = xstrndup(s, colon - s); + error_name = colon + 1; + + found = 0; + for (i = 0; i < ARRAY_SIZE(errnos); i++) { + if (strcmp(error_name, errnos[i].name) == 0) { + ret = errnos[i].number; + found = 1; + break; + } + } + if (!found) + ret = str2num_or_err( + colon + 1, 10, _("Unknown errno"), 0, INT_MAX); + } else { + name = s; + } + found = 0; - for (i = 0; i < nsyscalls; i++) { - if (strcmp(s, syscalls[i].name) == 0) { - blocked_number = syscalls[i].number; + for (i = 0; i < n_entities; i++) { + if (strcmp(name, entities[i].name) == 0) { + blocked_number = entities[i].number; found = 1; break; } } if (!found) blocked_number = str2num_or_err( - s, 10, _("Unknown syscall"), 0, LONG_MAX); + name, 10, _("Unknown syscall"), 0, LONG_MAX); blocked = xmalloc(sizeof(*blocked)); blocked->number = blocked_number; diff --git a/tests/expected/misc/enosys-basic b/tests/expected/misc/enosys-basic index 6552946f5..1569e8976 100644 --- a/tests/expected/misc/enosys-basic +++ b/tests/expected/misc/enosys-basic @@ -2,3 +2,5 @@ test_enosys: fallocate r=-1 errno=Bad file descriptor test_enosys: fallocate r=-1 errno=Function not implemented test_enosys: fallocate r=-1 errno=Function not implemented test_enosys: fallocate r=-1 errno=Function not implemented +test_enosys: fallocate r=-1 errno=Cannot allocate memory +test_enosys: fallocate r=-1 errno=Cannot allocate memory diff --git a/tests/expected/misc/enosys-ioctl b/tests/expected/misc/enosys-ioctl index 7ab1efd15..ffa521d61 100644 --- a/tests/expected/misc/enosys-ioctl +++ b/tests/expected/misc/enosys-ioctl @@ -3,3 +3,5 @@ test_enosys: ioctl r=-1 errno=Function not implemented test_enosys: ioctl r=-1 errno=Inappropriate ioctl for device test_enosys: ioctl r=-1 errno=Inappropriate ioctl for device test_enosys: ioctl r=-1 errno=Function not implemented +test_enosys: ioctl r=-1 errno=Cannot allocate memory +test_enosys: ioctl r=-1 errno=Cannot allocate memory diff --git a/tests/ts/misc/enosys b/tests/ts/misc/enosys index ae93c6306..e10cf008b 100755 --- a/tests/ts/misc/enosys +++ b/tests/ts/misc/enosys @@ -31,6 +31,8 @@ $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" "$TS_CMD_ENOSYS" -s fallocate $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" "$TS_CMD_ENOSYS" -s fsopen -s fallocate $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" "$TS_CMD_ENOSYS" -s fallocate -s fsopen $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" +"$TS_CMD_ENOSYS" -s fallocate:12 $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" +"$TS_CMD_ENOSYS" -s fallocate:ENOMEM $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" ts_finalize_subtest @@ -52,6 +54,8 @@ $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" "$TS_CMD_ENOSYS" -i FIOCLEX $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" "$TS_CMD_ENOSYS" -i "$("$TS_CMD_ENOSYS" -m | grep FIOCLEX | awk '{ print $1 }')" $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" "$TS_CMD_ENOSYS" -s ioctl -i FIOCLEX $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" +"$TS_CMD_ENOSYS" -i FIOCLEX:12 $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" +"$TS_CMD_ENOSYS" -i FIOCLEX:ENOMEM $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT" ts_finalize_subtest -- 2.47.3