summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-11-03 20:27:45 -0400
committerGitHub <noreply@github.com>2016-11-03 20:27:45 -0400
commitcf88547034d72e0c43e880b89d36643befc54bb9 (patch)
tree4baf2125530aadacc6ac73d5f80b843dad1ce2d1
parentd974f949f10d6945e1abe9bc6525e676bc515928 (diff)
parent1720590bfd7618efa10891f956bf4b265311be04 (diff)
Merge pull request #4548 from keszybz/seccomp-help
systemd-analyze syscall-filter
-rw-r--r--man/systemd-analyze.xml11
-rw-r--r--man/systemd.exec.xml16
-rw-r--r--shell-completion/bash/systemd-analyze6
-rw-r--r--shell-completion/zsh/_systemd-analyze1
-rw-r--r--src/analyze/analyze.c107
-rw-r--r--src/shared/seccomp-util.c68
-rw-r--r--src/shared/seccomp-util.h4
7 files changed, 151 insertions, 62 deletions
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index 8fa7cd3329..634e16b5f4 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -104,6 +104,12 @@
<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>
<arg choice="plain">verify</arg>
<arg choice="opt" rep="repeat"><replaceable>FILES</replaceable></arg>
</cmdsynopsis>
@@ -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
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index ea889c9cf3..0973f4047a 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -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>,
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
index 7a5f46ba1d..92ff13d316 100644
--- a/shell-completion/bash/systemd-analyze
+++ b/shell-completion/bash/systemd-analyze
@@ -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'
diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze
index efafddc686..0e670034c1 100644
--- a/shell-completion/zsh/_systemd-analyze
+++ b/shell-completion/zsh/_systemd-analyze
@@ -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'
)
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index cbf9354a7a..f744a84501 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -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]);
}
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index c9b24f1065..fc1f6b68f2 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -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"
diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
index 8e209efef2..f0b9f455ab 100644
--- a/src/shared/seccomp-util.h
+++ b/src/shared/seccomp-util.h
@@ -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,