]> git.ipfire.org Git - pakfire.git/commitdiff
execute: Filter syscalls in container
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 21 May 2022 12:50:10 +0000 (12:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 21 May 2022 12:50:10 +0000 (12:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/execute.c

index 37262e60d8784c6bb7fc4b3c67afbe301bb42fe7..b4aab537e32c1202dd92e5b1ba6556b13d9b7cb9 100644 (file)
@@ -36,6 +36,9 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+// libseccomp
+#include <seccomp.h>
+
 #include <pakfire/arch.h>
 #include <pakfire/cgroup.h>
 #include <pakfire/execute.h>
@@ -438,6 +441,53 @@ ERROR:
        return r;
 }
 
+static int pakfire_limit_syscalls(struct pakfire* pakfire) {
+       const int syscalls[] = {
+               // The kernel's keyring isn't namespaced
+               SCMP_SYS(keyctl),
+               SCMP_SYS(add_key),
+               SCMP_SYS(request_key),
+
+               // Disable userfaultfd
+               SCMP_SYS(userfaultfd),
+
+               // Disable perf which could leak a lot of information about the host
+               SCMP_SYS(perf_event_open),
+
+               0,
+       };
+       int r = 1;
+
+       // Setup a syscall filter which allows everything by default
+       scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
+       if (!ctx) {
+               ERROR(pakfire, "Could not setup seccomp filter: %m\n");
+               goto ERROR;
+       }
+
+       // All all syscalls
+       for (const int* syscall = syscalls; *syscall; syscall++) {
+               r = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), *syscall, 0);
+               if (r) {
+                       ERROR(pakfire, "Could not configure syscall %d: %m\n", *syscall);
+                       goto ERROR;
+               }
+       }
+
+       // Load syscall filter into the kernel
+       r = seccomp_load(ctx);
+       if (r) {
+               ERROR(pakfire, "Could not load syscall filter into the kernel: %m\n");
+               goto ERROR;
+       }
+
+ERROR:
+       if (ctx)
+               seccomp_release(ctx);
+
+       return r;
+}
+
 static int find_environ(struct pakfire_execute* env, const char* key) {
        if (!key) {
                errno = EINVAL;
@@ -557,6 +607,11 @@ static int pakfire_execute_fork(void* data) {
        if (r)
                return r;
 
+       // Filter syscalls
+       r = pakfire_limit_syscalls(pakfire);
+       if (r)
+               return r;
+
        // exec() command
        r = execvpe(env->argv[0], (char**)env->argv, env->envp);
        if (r < 0) {