summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2020-11-15 23:22:13 +0000
committerDaniel Golle <daniel@makrotopia.org>2020-11-15 23:54:13 +0000
commitd352e6e97fc5ce2b821b4f363ec545a4d7bdf783 (patch)
tree09ee71e54215e03d1ef6325815b4daee5c87396c
parentd8f36f537839c8301d3660b6ecac788c72bd7da7 (diff)
downloadprocd-d352e6e97fc5ce2b821b4f363ec545a4d7bdf783.tar.gz
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 <daniel@makrotopia.org>
-rw-r--r--CMakeLists.txt7
-rw-r--r--jail/seccomp.c92
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 <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
-#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);
}