mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-26 10:03:40 +03:00
Merge pull request #4548 from keszybz/seccomp-help
systemd-analyze syscall-filter
This commit is contained in:
commit
cf88547034
@ -101,6 +101,12 @@
|
||||
<arg choice="plain">set-log-target</arg>
|
||||
<arg choice="plain"><replaceable>TARGET</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<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>
|
||||
@ -181,6 +187,11 @@
|
||||
<option>--log-target=</option>, described in
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
|
||||
|
||||
<para><command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>...</optional></command>
|
||||
will list system calls contained in the specified system call set <replaceable>SET</replaceable>,
|
||||
or all known sets if no sets are specified. Argument <replaceable>SET</replaceable> must include
|
||||
the <literal>@</literal> prefix.</para>
|
||||
|
||||
<para><command>systemd-analyze verify</command> will load unit files and print
|
||||
warnings if any errors are detected. Files specified on the command line will be
|
||||
loaded, but also any other units referenced by them. The full unit search path is
|
||||
|
@ -1339,11 +1339,11 @@
|
||||
</row>
|
||||
<row>
|
||||
<entry>@module</entry>
|
||||
<entry>Kernel module control (<citerefentry project='man-pages'><refentrytitle>init_module</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>delete_module</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
|
||||
<entry>Loading and unloading of kernel modules (<citerefentry project='man-pages'><refentrytitle>init_module</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>delete_module</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>@mount</entry>
|
||||
<entry>File system mounting and unmounting (<citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
|
||||
<entry>Mounting and unmounting of file systems (<citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>@network-io</entry>
|
||||
@ -1359,7 +1359,7 @@
|
||||
</row>
|
||||
<row>
|
||||
<entry>@process</entry>
|
||||
<entry>Process control, execution, namespaces (<citerefentry project='man-pages'><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>, …</entry>
|
||||
<entry>Process control, execution, namespaceing operations (<citerefentry project='man-pages'><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>, …</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>@raw-io</entry>
|
||||
@ -1373,8 +1373,13 @@
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
Note that as new system calls are added to the kernel, additional system calls might be added to the groups
|
||||
above, so the contents of the sets may change between systemd versions.</para>
|
||||
Note, that as new system calls are added to the kernel, additional system calls might be
|
||||
added to the groups above. Contents of the sets may also change between systemd
|
||||
versions. In addition, the list of system calls depends on the kernel version and
|
||||
architecture for which systemd was compiled. Use
|
||||
<command>systemd-analyze syscall-filter</command> to list the actual list of system calls in
|
||||
each filter.
|
||||
</para>
|
||||
|
||||
<para>It is recommended to combine the file system namespacing related options with
|
||||
<varname>SystemCallFilter=~@mount</varname>, in order to prohibit the unit's processes to undo the
|
||||
@ -1844,6 +1849,7 @@
|
||||
<para>
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
|
@ -45,6 +45,7 @@ _systemd_analyze() {
|
||||
[DOT]='dot'
|
||||
[LOG_LEVEL]='set-log-level'
|
||||
[VERIFY]='verify'
|
||||
[SECCOMP_FILTER]='syscall-filter'
|
||||
)
|
||||
|
||||
_init_completion || return
|
||||
@ -100,6 +101,11 @@ _systemd_analyze() {
|
||||
comps='debug info notice warning err crit alert emerg'
|
||||
fi
|
||||
|
||||
elif __contains_word "$verb" ${VERBS[SECCOMP_FILTER]}; then
|
||||
if [[ $cur = -* ]]; then
|
||||
comps='--help --version'
|
||||
fi
|
||||
|
||||
elif __contains_word "$verb" ${VERBS[VERIFY]}; then
|
||||
if [[ $cur = -* ]]; then
|
||||
comps='--help --version --system --user --man'
|
||||
|
@ -21,6 +21,7 @@ _systemd_analyze_command(){
|
||||
'dot:Dump dependency graph (in dot(1) format)'
|
||||
'dump:Dump server status'
|
||||
'set-log-level:Set systemd log threshold'
|
||||
'syscall-filter:List syscalls in seccomp filter'
|
||||
'verify:Check unit files for correctness'
|
||||
)
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "log.h"
|
||||
#include "pager.h"
|
||||
#include "parse-util.h"
|
||||
#include "seccomp-util.h"
|
||||
#include "special.h"
|
||||
#include "strv.h"
|
||||
#include "strxcpyx.h"
|
||||
@ -1275,36 +1276,94 @@ static int set_log_target(sd_bus *bus, char **args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SECCOMP
|
||||
static void dump_syscall_filter(const SyscallFilterSet *set) {
|
||||
const char *syscall;
|
||||
|
||||
printf("%s\n", set->name);
|
||||
printf(" # %s\n", set->help);
|
||||
NULSTR_FOREACH(syscall, set->value)
|
||||
printf(" %s\n", syscall);
|
||||
}
|
||||
|
||||
static int dump_syscall_filters(char** names) {
|
||||
bool first = true;
|
||||
|
||||
pager_open(arg_no_pager, false);
|
||||
|
||||
if (strv_isempty(names)) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
|
||||
if (!first)
|
||||
puts("");
|
||||
dump_syscall_filter(syscall_filter_sets + i);
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
char **name;
|
||||
|
||||
STRV_FOREACH(name, names) {
|
||||
const SyscallFilterSet *set;
|
||||
|
||||
if (!first)
|
||||
puts("");
|
||||
|
||||
set = syscall_filter_set_find(*name);
|
||||
if (!set) {
|
||||
/* make sure the error appears below normal output */
|
||||
fflush(stdout);
|
||||
|
||||
log_error("Filter set \"%s\" not found.", *name);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
dump_syscall_filter(set);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
static int dump_syscall_filters(char** names) {
|
||||
log_error("Not compiled with syscall filters, sorry.");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void help(void) {
|
||||
|
||||
pager_open(arg_no_pager, false);
|
||||
|
||||
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
|
||||
"Profile systemd, show unit dependencies, check unit files.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --system Operate on system systemd instance\n"
|
||||
" --user Operate on user systemd instance\n"
|
||||
" -H --host=[USER@]HOST Operate on remote host\n"
|
||||
" -M --machine=CONTAINER Operate on local container\n"
|
||||
" --order Show only order in the graph\n"
|
||||
" --require Show only requirement in the graph\n"
|
||||
" --from-pattern=GLOB Show only origins in the graph\n"
|
||||
" --to-pattern=GLOB Show only destinations in the graph\n"
|
||||
" --fuzz=SECONDS Also print also services which finished SECONDS\n"
|
||||
" earlier than the latest in the branch\n"
|
||||
" --man[=BOOL] Do [not] check for existence of man pages\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --system Operate on system systemd instance\n"
|
||||
" --user Operate on user systemd instance\n"
|
||||
" -H --host=[USER@]HOST Operate on remote host\n"
|
||||
" -M --machine=CONTAINER Operate on local container\n"
|
||||
" --order Show only order in the graph\n"
|
||||
" --require Show only requirement in the graph\n"
|
||||
" --from-pattern=GLOB Show only origins in the graph\n"
|
||||
" --to-pattern=GLOB Show only destinations in the graph\n"
|
||||
" --fuzz=SECONDS Also print also services which finished SECONDS\n"
|
||||
" earlier than the latest in the branch\n"
|
||||
" --man[=BOOL] Do [not] check for existence of man pages\n\n"
|
||||
"Commands:\n"
|
||||
" time Print time spent in the kernel\n"
|
||||
" blame Print list of running units ordered by time to init\n"
|
||||
" critical-chain Print a tree of the time critical chain of units\n"
|
||||
" plot Output SVG graphic showing service initialization\n"
|
||||
" dot Output dependency graph in dot(1) format\n"
|
||||
" set-log-level LEVEL Set logging threshold for manager\n"
|
||||
" set-log-target TARGET Set logging target for manager\n"
|
||||
" dump Output state serialization of service manager\n"
|
||||
" verify FILE... Check unit files for correctness\n"
|
||||
" time Print time spent in the kernel\n"
|
||||
" blame Print list of running units ordered by time to init\n"
|
||||
" critical-chain Print a tree of the time critical chain of units\n"
|
||||
" plot Output SVG graphic showing service initialization\n"
|
||||
" dot Output dependency graph in dot(1) format\n"
|
||||
" set-log-level LEVEL Set logging threshold for manager\n"
|
||||
" set-log-target TARGET Set logging target for manager\n"
|
||||
" dump Output state serialization of service manager\n"
|
||||
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
|
||||
" verify FILE... Check unit files for correctness\n"
|
||||
, program_invocation_short_name);
|
||||
|
||||
/* When updating this list, including descriptions, apply
|
||||
@ -1471,6 +1530,8 @@ int main(int argc, char *argv[]) {
|
||||
r = set_log_level(bus, argv+optind+1);
|
||||
else if (streq(argv[optind], "set-log-target"))
|
||||
r = set_log_target(bus, argv+optind+1);
|
||||
else if (streq(argv[optind], "syscall-filter"))
|
||||
r = dump_syscall_filters(argv+optind+1);
|
||||
else
|
||||
log_error("Unknown operation '%s'.", argv[optind]);
|
||||
}
|
||||
|
@ -217,9 +217,27 @@ bool is_seccomp_available(void) {
|
||||
}
|
||||
|
||||
const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
[SYSCALL_FILTER_SET_DEFAULT] = {
|
||||
.name = "@default",
|
||||
.help = "System calls that are always permitted",
|
||||
.value =
|
||||
"clock_getres\0"
|
||||
"clock_gettime\0"
|
||||
"clock_nanosleep\0"
|
||||
"execve\0"
|
||||
"exit\0"
|
||||
"exit_group\0"
|
||||
"getrlimit\0" /* make sure processes can query stack size and such */
|
||||
"gettimeofday\0"
|
||||
"nanosleep\0"
|
||||
"pause\0"
|
||||
"rt_sigreturn\0"
|
||||
"sigreturn\0"
|
||||
"time\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_BASIC_IO] = {
|
||||
/* Basic IO */
|
||||
.name = "@basic-io",
|
||||
.help = "Basic IO",
|
||||
.value =
|
||||
"close\0"
|
||||
"dup2\0"
|
||||
@ -236,8 +254,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"writev\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_CLOCK] = {
|
||||
/* Clock */
|
||||
.name = "@clock",
|
||||
.help = "Change the system time",
|
||||
.value =
|
||||
"adjtimex\0"
|
||||
"clock_adjtime\0"
|
||||
@ -246,8 +264,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"stime\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_CPU_EMULATION] = {
|
||||
/* CPU emulation calls */
|
||||
.name = "@cpu-emulation",
|
||||
.help = "System calls for CPU emulation functionality",
|
||||
.value =
|
||||
"modify_ldt\0"
|
||||
"subpage_prot\0"
|
||||
@ -256,8 +274,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"vm86old\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_DEBUG] = {
|
||||
/* Debugging/Performance Monitoring/Tracing */
|
||||
.name = "@debug",
|
||||
.help = "Debugging, performance monitoring and tracing functionality",
|
||||
.value =
|
||||
"lookup_dcookie\0"
|
||||
"perf_event_open\0"
|
||||
@ -270,27 +288,9 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
#endif
|
||||
"sys_debug_setcontext\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_DEFAULT] = {
|
||||
/* Default list: the most basic of operations */
|
||||
.name = "@default",
|
||||
.value =
|
||||
"clock_getres\0"
|
||||
"clock_gettime\0"
|
||||
"clock_nanosleep\0"
|
||||
"execve\0"
|
||||
"exit\0"
|
||||
"exit_group\0"
|
||||
"getrlimit\0" /* make sure processes can query stack size and such */
|
||||
"gettimeofday\0"
|
||||
"nanosleep\0"
|
||||
"pause\0"
|
||||
"rt_sigreturn\0"
|
||||
"sigreturn\0"
|
||||
"time\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_IO_EVENT] = {
|
||||
/* Event loop use */
|
||||
.name = "@io-event",
|
||||
.help = "Event loop system calls",
|
||||
.value =
|
||||
"_newselect\0"
|
||||
"epoll_create1\0"
|
||||
@ -308,9 +308,10 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"select\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_IPC] = {
|
||||
/* Message queues, SYSV IPC or other IPC */
|
||||
.name = "@ipc",
|
||||
.value = "ipc\0"
|
||||
.help = "SysV IPC, POSIX Message Queues or other IPC",
|
||||
.value =
|
||||
"ipc\0"
|
||||
"memfd_create\0"
|
||||
"mq_getsetattr\0"
|
||||
"mq_notify\0"
|
||||
@ -336,24 +337,24 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"shmget\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_KEYRING] = {
|
||||
/* Keyring */
|
||||
.name = "@keyring",
|
||||
.help = "Kernel keyring access",
|
||||
.value =
|
||||
"add_key\0"
|
||||
"keyctl\0"
|
||||
"request_key\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_MODULE] = {
|
||||
/* Kernel module control */
|
||||
.name = "@module",
|
||||
.help = "Loading and unloading of kernel modules",
|
||||
.value =
|
||||
"delete_module\0"
|
||||
"finit_module\0"
|
||||
"init_module\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_MOUNT] = {
|
||||
/* Mounting */
|
||||
.name = "@mount",
|
||||
.help = "Mounting and unmounting of file systems",
|
||||
.value =
|
||||
"chroot\0"
|
||||
"mount\0"
|
||||
@ -362,8 +363,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"umount\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_NETWORK_IO] = {
|
||||
/* Network or Unix socket IO, should not be needed if not network facing */
|
||||
.name = "@network-io",
|
||||
.help = "Network or Unix socket IO, should not be needed if not network facing",
|
||||
.value =
|
||||
"accept4\0"
|
||||
"accept\0"
|
||||
@ -388,8 +389,9 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"socketpair\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_OBSOLETE] = {
|
||||
/* Unusual, obsolete or unimplemented, some unknown even to libseccomp */
|
||||
/* some unknown even to libseccomp */
|
||||
.name = "@obsolete",
|
||||
.help = "Unusual, obsolete or unimplemented system calls",
|
||||
.value =
|
||||
"_sysctl\0"
|
||||
"afs_syscall\0"
|
||||
@ -417,8 +419,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"vserver\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_PRIVILEGED] = {
|
||||
/* Nice grab-bag of all system calls which need superuser capabilities */
|
||||
.name = "@privileged",
|
||||
.help = "All system calls which need super-user capabilities",
|
||||
.value =
|
||||
"@clock\0"
|
||||
"@module\0"
|
||||
@ -459,8 +461,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"vhangup\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_PROCESS] = {
|
||||
/* Process control, execution, namespaces */
|
||||
.name = "@process",
|
||||
.help = "Process control, execution, namespaceing operations",
|
||||
.value =
|
||||
"arch_prctl\0"
|
||||
"clone\0"
|
||||
@ -475,8 +477,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
"vfork\0"
|
||||
},
|
||||
[SYSCALL_FILTER_SET_RAW_IO] = {
|
||||
/* Raw I/O ports */
|
||||
.name = "@raw-io",
|
||||
.help = "Raw I/O port access",
|
||||
.value =
|
||||
"ioperm\0"
|
||||
"iopl\0"
|
||||
|
@ -34,15 +34,17 @@ bool is_seccomp_available(void);
|
||||
|
||||
typedef struct SyscallFilterSet {
|
||||
const char *name;
|
||||
const char *help;
|
||||
const char *value;
|
||||
} SyscallFilterSet;
|
||||
|
||||
enum {
|
||||
/* Please leave DEFAULT first, but sort the rest alphabetically */
|
||||
SYSCALL_FILTER_SET_DEFAULT,
|
||||
SYSCALL_FILTER_SET_BASIC_IO,
|
||||
SYSCALL_FILTER_SET_CLOCK,
|
||||
SYSCALL_FILTER_SET_CPU_EMULATION,
|
||||
SYSCALL_FILTER_SET_DEBUG,
|
||||
SYSCALL_FILTER_SET_DEFAULT,
|
||||
SYSCALL_FILTER_SET_IO_EVENT,
|
||||
SYSCALL_FILTER_SET_IPC,
|
||||
SYSCALL_FILTER_SET_KEYRING,
|
||||
|
Loading…
x
Reference in New Issue
Block a user