1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-02 02:21:44 +03:00

Merge pull request #10777 from poettering/seccomp-filter-others

list syscalls supported by the local kernel but not in any syscall groups explicitly in "systemd-analyze syscall-filter"
This commit is contained in:
Lennart Poettering 2018-11-16 17:53:50 +01:00 committed by GitHub
commit ca0e33734e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 5 deletions

View File

@ -21,6 +21,7 @@
#include "conf-files.h"
#include "copy.h"
#include "fd-util.h"
#include "fileio.h"
#include "glob-util.h"
#include "hashmap.h"
#include "locale-util.h"
@ -1497,13 +1498,76 @@ static int dump_unit_paths(int argc, char *argv[], void *userdata) {
}
#if HAVE_SECCOMP
static int load_kernel_syscalls(Set **ret) {
_cleanup_(set_free_freep) Set *syscalls = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
/* Let's read the available system calls from the list of available tracing events. Slightly dirty, but good
* enough for analysis purposes. */
f = fopen("/sys/kernel/debug/tracing/available_events", "re");
if (!f)
return log_full_errno(IN_SET(errno, EPERM, EACCES, ENOENT) ? LOG_DEBUG : LOG_WARNING, errno, "Can't read open /sys/kernel/debug/tracing/available_events: %m");
for (;;) {
_cleanup_free_ char *line = NULL;
const char *e;
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read system call list: %m");
if (r == 0)
break;
e = startswith(line, "syscalls:sys_enter_");
if (!e)
continue;
/* These are named differently inside the kernel than their external name for historical reasons. Let's hide them here. */
if (STR_IN_SET(e, "newuname", "newfstat", "newstat", "newlstat", "sysctl"))
continue;
r = set_ensure_allocated(&syscalls, &string_hash_ops);
if (r < 0)
return log_oom();
r = set_put_strdup(syscalls, e);
if (r < 0)
return log_error_errno(r, "Failed to add system call to list: %m");
}
*ret = TAKE_PTR(syscalls);
return 0;
}
static void kernel_syscalls_remove(Set *s, const SyscallFilterSet *set) {
const char *syscall;
NULSTR_FOREACH(syscall, set->value) {
if (syscall[0] == '@')
continue;
(void) set_remove(s, syscall);
}
}
static void dump_syscall_filter(const SyscallFilterSet *set) {
const char *syscall;
printf("%s\n", set->name);
printf(" # %s\n", set->help);
printf("%s%s%s\n"
" # %s\n",
ansi_highlight(),
set->name,
ansi_normal(),
set->help);
NULSTR_FOREACH(syscall, set->value)
printf(" %s\n", syscall);
printf(" %s%s%s\n",
syscall[0] == '@' ? ansi_underline() : "",
syscall,
ansi_normal());
}
static int dump_syscall_filters(int argc, char *argv[], void *userdata) {
@ -1512,14 +1576,36 @@ static int dump_syscall_filters(int argc, char *argv[], void *userdata) {
(void) pager_open(arg_pager_flags);
if (strv_isempty(strv_skip(argv, 1))) {
int i;
_cleanup_(set_free_freep) Set *kernel = NULL;
int i, k;
k = load_kernel_syscalls(&kernel);
for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
const SyscallFilterSet *set = syscall_filter_sets + i;
if (!first)
puts("");
dump_syscall_filter(syscall_filter_sets + i);
dump_syscall_filter(set);
kernel_syscalls_remove(kernel, set);
first = false;
}
if (k < 0) {
fputc('\n', stdout);
fflush(stdout);
log_notice_errno(k, "# Not showing unlisted system calls, couldn't retrieve kernel system call list: %m");
} else if (!set_isempty(kernel)) {
const char *syscall;
Iterator j;
printf("\n"
"# %sUnlisted System Calls%s (supported by the local kernel, but not included in any of the groups listed above):\n",
ansi_highlight(), ansi_normal());
SET_FOREACH(syscall, kernel, j)
printf("# %s\n", syscall);
}
} else {
char **name;

View File

@ -308,6 +308,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"io_cancel\0"
"io_destroy\0"
"io_getevents\0"
"io_pgetevents\0"
"io_setup\0"
"io_submit\0"
},
@ -619,7 +620,9 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"bpf\0"
"capset\0"
"chroot\0"
"fanotify_init\0"
"nfsservctl\0"
"open_by_handle_at\0"
"pivot_root\0"
"quotactl\0"
"setdomainname\0"