From d352e6e97fc5ce2b821b4f363ec545a4d7bdf783 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sun, 15 Nov 2020 23:22:13 +0000 Subject: [PATCH] seccomp: switch to new OCI compliant parser Drop the old OpenWrt-specific seccomp rule parser in favour of reusing the OCI compliant variant. Signed-off-by: Daniel Golle --- CMakeLists.txt | 7 ++-- jail/seccomp.c | 92 ++++---------------------------------------------- 2 files changed, 8 insertions(+), 91 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d20e57b..4d323ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,16 +102,13 @@ ADD_CUSTOM_TARGET(capabilities-names-h DEPENDS capabilities-names.h) IF(SECCOMP_SUPPORT) ADD_DEFINITIONS(-DSECCOMP_SUPPORT) -ADD_LIBRARY(preload-seccomp SHARED jail/preload.c jail/seccomp.c) +ADD_LIBRARY(preload-seccomp SHARED jail/preload.c jail/seccomp.c jail/seccomp-oci.c) TARGET_LINK_LIBRARIES(preload-seccomp dl ${ubox} ${blobmsg_json}) INSTALL(TARGETS preload-seccomp LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) ADD_DEPENDENCIES(preload-seccomp syscall-names-h) -endif() - -IF(SECCOMP_SUPPORT) - SET(SOURCES_OCI_SECCOMP jail/seccomp-oci.c) +SET(SOURCES_OCI_SECCOMP jail/seccomp-oci.c) ENDIF() IF(JAIL_SUPPORT) diff --git a/jail/seccomp.c b/jail/seccomp.c index dac4245..4483c33 100644 --- a/jail/seccomp.c +++ b/jail/seccomp.c @@ -18,30 +18,13 @@ #include #include -#include "seccomp-bpf.h" #include "seccomp.h" -#include "../syscall-names.h" -#include "seccomp-syscalls-helpers.h" +#include "seccomp-oci.h" int install_syscall_filter(const char *argv, const char *file) { - enum { - SECCOMP_WHITELIST, - SECCOMP_POLICY, - __SECCOMP_MAX - }; - static const struct blobmsg_policy policy[__SECCOMP_MAX] = { - [SECCOMP_WHITELIST] = { .name = "whitelist", .type = BLOBMSG_TYPE_ARRAY }, - [SECCOMP_POLICY] = { .name = "policy", .type = BLOBMSG_TYPE_INT32 }, - }; struct blob_buf b = { 0 }; - struct blob_attr *tb[__SECCOMP_MAX]; - struct blob_attr *cur; - int rem; - - struct sock_filter *filter; - struct sock_fprog prog = { 0 }; - int sz = 5, idx = 0, default_policy = 0; + struct sock_fprog *prog = NULL; INFO("%s: setting up syscall filter\n", argv); @@ -51,74 +34,11 @@ int install_syscall_filter(const char *argv, const char *file) return -1; } - blobmsg_parse(policy, __SECCOMP_MAX, tb, blob_data(b.head), blob_len(b.head)); - if (!tb[SECCOMP_WHITELIST]) { - ERROR("%s: %s is missing the syscall table\n", argv, file); - return -1; - } - - if (tb[SECCOMP_POLICY]) - default_policy = blobmsg_get_u32(tb[SECCOMP_POLICY]); - - blobmsg_for_each_attr(cur, tb[SECCOMP_WHITELIST], rem) - sz += 2; - - filter = calloc(sz, sizeof(struct sock_filter)); - if (!filter) { - ERROR("failed to allocate filter memory\n"); + prog = parseOCIlinuxseccomp(b.head); + if (!prog) { + ERROR("%s: failed to parse seccomp filter rules %s\n", argv, file); return -1; } - /* validate arch */ - set_filter(&filter[idx++], BPF_LD + BPF_W + BPF_ABS, 0, 0, arch_nr); - set_filter(&filter[idx++], BPF_JMP + BPF_JEQ + BPF_K, 1, 0, ARCH_NR); - set_filter(&filter[idx++], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_KILL); - - /* get syscall */ - set_filter(&filter[idx++], BPF_LD + BPF_W + BPF_ABS, 0, 0, syscall_nr); - - blobmsg_for_each_attr(cur, tb[SECCOMP_WHITELIST], rem) { - char *name = blobmsg_get_string(cur); - int nr; - - if (!name) { - INFO("%s: invalid syscall name\n", argv); - continue; - } - - nr = find_syscall(name); - if (nr == -1) { - INFO("%s: unknown syscall %s\n", argv, name); - continue; - } - - /* add whitelist */ - set_filter(&filter[idx++], BPF_JMP + BPF_JEQ + BPF_K, 0, 1, nr); - set_filter(&filter[idx++], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_ALLOW); - } - - if (default_policy) - /* notify tracer; without tracer return -1 and set errno to ENOSYS */ - set_filter(&filter[idx], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_TRACE); - else - /* kill the process */ - set_filter(&filter[idx], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_KILL); - - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { - ERROR("%s: prctl(PR_SET_NO_NEW_PRIVS) failed: %m\n", argv); - goto errout; - } - - prog.len = (unsigned short) idx + 1; - prog.filter = filter; - - if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { - ERROR("%s: prctl(PR_SET_SECCOMP) failed: %m\n", argv); - goto errout; - } - return 0; - -errout: - free(filter); - return errno; + return applyOCIlinuxseccomp(prog); } -- 2.30.2