mirror of
https://github.com/systemd/systemd.git
synced 2026-11-06 05:17:24 +00:00
analyze: add io-uring-filter verb
IOUringFilter= takes the names of io_uring operations, and SystemCallFilter= denies an operation if it denies one of the system calls that the operation can do the work of. Users can only find the operation names and the system calls of each operation in the source code. Let's add "systemd-analyze io-uring-filter", which lists the operations that systemd knows, together with the system calls of each operation, like "systemd-analyze syscall-filter" does for the system call groups.
This commit is contained in:
1 parent
9dcd9ffd89
commit
846cafe9ae
9 files changed
+147
-4
No files matched your search
@@ -116,6 +116,12 @@
|
||||
<arg choice="plain">syscall-filter</arg>
|
||||
<arg choice="opt"><replaceable>SET</replaceable>…</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">io-uring-filter</arg>
|
||||
<arg choice="opt"><replaceable>NAME</replaceable>…</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
@@ -600,6 +606,31 @@ Conditions succeeded.</programlisting>
|
||||
<replaceable>SET</replaceable> must include the <literal>@</literal> prefix.</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title><command>systemd-analyze io-uring-filter <optional><replaceable>NAME</replaceable>...</optional></command></title>
|
||||
|
||||
<para>Lists the
|
||||
<citerefentry project='man-pages'><refentrytitle>io_uring</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
operations that systemd knows, or only the operations with the specified names. The names are the ones
|
||||
that <varname>IOUringFilter=</varname> takes, see
|
||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>. For
|
||||
each operation, the <literal>SYSCALLS</literal> column lists the system calls whose work the operation
|
||||
can do. <varname>SystemCallFilter=</varname> denies an operation if it denies any of the listed system
|
||||
calls.</para>
|
||||
|
||||
<example>
|
||||
<title>Table output</title>
|
||||
<programlisting>$ systemd-analyze io-uring-filter nop read socket uring_cmd
|
||||
NAME SYSCALLS
|
||||
nop -
|
||||
read read pread64
|
||||
socket socket
|
||||
uring_cmd ioctl setsockopt getsockopt getsockname</programlisting>
|
||||
</example>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v263"/>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title><command>systemd-analyze filesystems <optional><replaceable>SET</replaceable>...</optional></command></title>
|
||||
|
||||
|
||||
@@ -2539,7 +2539,8 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
||||
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.</para>
|
||||
are ignored. Use <command>systemd-analyze io-uring-filter</command> to list the operations that
|
||||
systemd knows.</para>
|
||||
|
||||
<para>This option may be specified more than once, in which case the lists are merged. If the first
|
||||
assignment starts with <literal>~</literal>, the list is a deny list, otherwise it is an allow list.
|
||||
@@ -3043,7 +3044,8 @@ RestrictNamespaces=~cgroup net</programlisting>
|
||||
if the filter allows <function>io_uring_setup()</function>. An operation that can do the work of
|
||||
one or more system calls, such as <constant>IORING_OP_OPENAT</constant> or
|
||||
<constant>IORING_OP_SOCKET</constant>, 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. <command>systemd-analyze io-uring-filter</command> 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 <constant>EACCES</constant>, regardless of
|
||||
<varname>SystemCallErrorNumber=</varname> 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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <linux/io_uring.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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),
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user