]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Apply syscall filter
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 14:47:34 +0000 (14:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 14:47:34 +0000 (14:47 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/jail.c

index 457baed56c640a46afff98c3399426da6b73acdd..c72d1a6fb528806af6f3decc7792a5a9af022b7d 100644 (file)
@@ -32,6 +32,9 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+// libseccomp
+#include <seccomp.h>
+
 #include <pakfire/arch.h>
 #include <pakfire/jail.h>
 #include <pakfire/logging.h>
@@ -341,6 +344,57 @@ ERROR:
        return r;
 }
 
+// Syscall Filter
+
+static int pakfire_jail_limit_syscalls(struct pakfire_jail* jail) {
+       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;
+
+       DEBUG(jail->pakfire, "Applying syscall filter...\n");
+
+       // Setup a syscall filter which allows everything by default
+       scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
+       if (!ctx) {
+               ERROR(jail->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(jail->pakfire, "Could not configure syscall %d: %m\n", *syscall);
+                       goto ERROR;
+               }
+       }
+
+       // Load syscall filter into the kernel
+       r = seccomp_load(ctx);
+       if (r) {
+               ERROR(jail->pakfire, "Could not load syscall filter into the kernel: %m\n");
+               goto ERROR;
+       }
+
+ERROR:
+       if (ctx)
+               seccomp_release(ctx);
+
+       return r;
+}
+
 // UID/GID Mapping
 
 static int pakfire_jail_write_uidgid_mapping(struct pakfire_jail* jail,
@@ -586,6 +640,11 @@ static int pakfire_jail_child(struct pakfire_jail* jail, const char* argv[], int
        if (r)
                return r;
 
+       // Filter syscalls
+       r = pakfire_jail_limit_syscalls(jail);
+       if (r)
+               return r;
+
        // exec() command
        r = execvpe(argv[0], (char**)argv, jail->env);
        if (r < 0)