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.
+
+ systemd-analyze io-uring-filter NAME...
+
+ 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
+
+
+
+
+
systemd-analyze filesystems SET...
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