diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index e77f8ad62a2..084ababf9a3 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -116,6 +116,12 @@ syscall-filter SET… + + systemd-analyze + OPTIONS + io-uring-filter + NAME… + systemd-analyze OPTIONS @@ -600,6 +606,31 @@ Conditions succeeded. SET must include the @ prefix. + + <command>systemd-analyze io-uring-filter <optional><replaceable>NAME</replaceable>...</optional></command> + + Lists the + io_uring7 + operations that systemd knows, or only the operations with the specified names. The names are the ones + that IOUringFilter= takes, see + systemd.exec5. For + each operation, the SYSCALLS column lists the system calls whose work the operation + can do. SystemCallFilter= denies an operation if it denies any of the listed system + calls. + + + Table output + $ systemd-analyze io-uring-filter nop read socket uring_cmd +NAME SYSCALLS +nop - +read read pread64 +socket socket +uring_cmd ioctl setsockopt getsockopt getsockname + + + + + <command>systemd-analyze filesystems <optional><replaceable>SET</replaceable>...</optional></command> diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 7d557e45945..69649f7f9b9 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2539,7 +2539,8 @@ BindReadOnlyPaths=/var/lib/systemd listed operations are denied (deny-listing). Otherwise, only the listed operations are allowed (allow-listing). An allow list also denies the operations of newer kernels that systemd doesn't know, even though the kernel reports them as supported. Operation names that systemd doesn't know - are ignored. + are ignored. Use systemd-analyze io-uring-filter to list the operations that + systemd knows. This option may be specified more than once, in which case the lists are merged. If the first assignment starts with ~, the list is a deny list, otherwise it is an allow list. @@ -3043,7 +3044,8 @@ RestrictNamespaces=~cgroup net if the filter allows io_uring_setup(). An operation that can do the work of one or more system calls, such as IORING_OP_OPENAT or IORING_OP_SOCKET, is denied if the filter denies any of its equivalent system - calls. Operations of newer kernels that systemd doesn't know are not affected. Denied requests + calls. systemd-analyze io-uring-filter lists the equivalent system calls of each + operation. Operations of newer kernels that systemd doesn't know are not affected. Denied requests always fail with EACCES, regardless of SystemCallErrorNumber= and of the action of the system call. System calls that are denied with an error number of 0 do not affect io_uring operations, since a denied request diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze index 719c3f53918..dca628a48b8 100644 --- a/shell-completion/bash/systemd-analyze +++ b/shell-completion/bash/systemd-analyze @@ -52,6 +52,10 @@ __get_syscall_sets() { done } +__get_io_uring_ops() { + systemd-analyze --no-legend --no-pager io-uring-filter 2>/dev/null | { while read -r a b; do echo " $a"; done; } +} + __get_architectures() { systemd-analyze --no-legend --no-pager architectures 2>/dev/null | { while read -r a b; do echo " $a"; done; } } @@ -88,6 +92,7 @@ _systemd_analyze() { [DUMP]='dump' [VERIFY]='verify' [SECCOMP_FILTER]='syscall-filter' + [IO_URING_FILTER]='io-uring-filter' [CAT_CONFIG]='cat-config' [SECURITY]='security' [CONDITION]='condition' @@ -249,6 +254,13 @@ _systemd_analyze() { comps='--help --version --system --user --global --no-pager --json=off --json=pretty --json=short --table --no-legend --scale-svg --detailed' fi + elif __contains_word "$verb" ${VERBS[IO_URING_FILTER]}; then + if [[ $cur = -* ]]; then + comps='--help --version --no-pager --json=off --json=pretty --json=short --no-legend' + else + comps=$( __get_io_uring_ops ) + fi + elif __contains_word "$verb" ${VERBS[ARCHITECTURES]}; then if [[ $cur = -* ]]; then comps='--help --version --no-pager --json=off --json=pretty --json=short --no-legend' diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze index e6dbbcde400..e91f47966a9 100644 --- a/shell-completion/zsh/_systemd-analyze +++ b/shell-completion/zsh/_systemd-analyze @@ -43,6 +43,13 @@ _describe -t groups 'syscall groups' _groups || compadd "$@" } +(( $+functions[_systemd-analyze_io-uring-filter] )) || + _systemd-analyze_io-uring-filter() { + local -a _ops + _ops=( $(systemd-analyze --quiet --no-pager --no-legend io-uring-filter 2>/dev/null | { while read -r a b; do echo " $a"; done; }) ) + _describe -t operations 'io_uring operations' _ops || compadd "$@" + } + (( $+functions[_systemd-analyze_filesystems] )) || _systemd-analyze_filesystems() { local -a _groups @@ -95,6 +102,7 @@ 'exit-status:List known exit statuses' 'capability:List capability definitions' 'syscall-filter:List syscalls in seccomp filters' + 'io-uring-filter:List io_uring operations' 'filesystems:List known filesystems' 'condition:Evaluate Condition*= and Assert*= assignments' 'verify:Check unit files for correctness' diff --git a/src/analyze/analyze-io-uring-filter.c b/src/analyze/analyze-io-uring-filter.c new file mode 100644 index 00000000000..96a46e3de7a --- /dev/null +++ b/src/analyze/analyze-io-uring-filter.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include + +#include "analyze.h" +#include "analyze-io-uring-filter.h" +#include "format-table.h" +#include "io-uring-filter.h" +#include "log.h" +#include "nulstr-util.h" +#include "strv.h" + +static int add_op(Table *t, int op) { + _cleanup_strv_free_ char **syscalls = NULL; + const char *s; + int r; + + assert(t); + + s = io_uring_op_syscalls_to_string(op); + if (s) { + syscalls = strv_split_nulstr(s); + if (!syscalls) + return log_oom(); + } + + r = table_add_many(t, + TABLE_INT, op, + TABLE_STRING, io_uring_op_to_string(op), + TABLE_STRV_WRAPPED, syscalls); + if (r < 0) + return table_log_add_error(r); + + return 0; +} + +int verb_io_uring_filter(int argc, char *argv[], uintptr_t _data, void *userdata) { + _cleanup_(table_unrefp) Table *table = NULL; + int r; + + table = table_new("opcode", "name", "syscalls"); + if (!table) + return log_oom(); + + (void) table_hide_column_from_display(table, (size_t) 0); + table_set_ersatz_string(table, TABLE_ERSATZ_DASH); + + char **args = strv_skip(argv, 1); + if (args) { + STRV_FOREACH(arg, args) { + int op; + + op = io_uring_op_from_string(*arg); + if (op < 0) + return log_error_errno(op, "io_uring operation \"%s\" not known.", *arg); + + r = add_op(table, op); + if (r < 0) + return r; + } + + (void) table_set_sort(table, (size_t) 0); + } else + for (int op = 0; op < IORING_OP_LAST; op++) { + r = add_op(table, op); + if (r < 0) + return r; + } + + r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend); + if (r < 0) + return r; + + return EXIT_SUCCESS; +} diff --git a/src/analyze/analyze-io-uring-filter.h b/src/analyze/analyze-io-uring-filter.h new file mode 100644 index 00000000000..3bd41b2bcd7 --- /dev/null +++ b/src/analyze/analyze-io-uring-filter.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "forward.h" + +int verb_io_uring_filter(int argc, char *argv[], uintptr_t _data, void *userdata); diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 71a8a9ea3f4..083854b1290 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -31,6 +31,7 @@ #include "analyze-has-tpm2.h" #include "analyze-image-policy.h" #include "analyze-inspect-elf.h" +#include "analyze-io-uring-filter.h" #include "analyze-log-control.h" #include "analyze-malloc.h" #include "analyze-nvpcrs.h" @@ -241,6 +242,8 @@ VERB_SCOPE(, verb_capabilities, "capability", "[CAP...]\0", VERB_ANY, VERB_ANY, "List capability definitions"); VERB_SCOPE(, verb_syscall_filters, "syscall-filter", "[NAME...]\0", VERB_ANY, VERB_ANY, 0, "List syscalls in seccomp filters"); +VERB_SCOPE(, verb_io_uring_filter, "io-uring-filter", "[NAME...]\0", VERB_ANY, VERB_ANY, 0, + "List io_uring operations"); VERB_SCOPE(, verb_filesystems, "filesystems", "[NAME...]\0", VERB_ANY, VERB_ANY, 0, "List known filesystems"); VERB_SCOPE(, verb_architectures, "architectures", "[NAME...]\0", VERB_ANY, VERB_ANY, 0, @@ -587,9 +590,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) { !STRPTR_IN_SET(verb, "security", "inspect-elf", "dlopen-metadata", "plot", "fdstore", "pcrs", "nvpcrs", "architectures", "cpu-features", "capability", "exit-status", "chid", "blame", - "identify-tpm2", "restart-delays")) + "identify-tpm2", "restart-delays", "io-uring-filter")) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --json= is only supported for security, inspect-elf, dlopen-metadata, plot, fdstore, pcrs, nvpcrs, architectures, cpu-features, capability, exit-status, chid, blame, identify-tpm2, restart-delays right now."); + "Option --json= is only supported for security, inspect-elf, dlopen-metadata, plot, fdstore, pcrs, nvpcrs, architectures, cpu-features, capability, exit-status, chid, blame, identify-tpm2, restart-delays, io-uring-filter right now."); if (arg_threshold != 100 && !streq_ptr(verb, "security")) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), diff --git a/src/analyze/meson.build b/src/analyze/meson.build index 3ba3b354707..9f874ba92c4 100644 --- a/src/analyze/meson.build +++ b/src/analyze/meson.build @@ -20,6 +20,7 @@ systemd_analyze_sources = files( 'analyze-has-tpm2.c', 'analyze-image-policy.c', 'analyze-inspect-elf.c', + 'analyze-io-uring-filter.c', 'analyze-log-control.c', 'analyze-malloc.c', 'analyze-nvpcrs.c', diff --git a/test/units/TEST-65-ANALYZE.sh b/test/units/TEST-65-ANALYZE.sh index 0e91c76dc58..8a296bea845 100755 --- a/test/units/TEST-65-ANALYZE.sh +++ b/test/units/TEST-65-ANALYZE.sh @@ -150,6 +150,10 @@ systemd-analyze syscall-filter @chown @sync systemd-analyze syscall-filter @sync @sync @sync (! systemd-analyze syscall-filter @chown @sync @foobar) (! systemd-analyze syscall-filter --global) +systemd-analyze io-uring-filter >/dev/null +systemd-analyze io-uring-filter nop read uring_cmd +systemd-analyze io-uring-filter --json=short socket | jq -e '.[0] == {"name": "socket", "syscalls": ["socket"]}' +(! systemd-analyze io-uring-filter read foobar) # filesystems (requires libbpf support) if systemctl --version | grep "+BPF_FRAMEWORK"; then systemd-analyze filesystems >/dev/null