#include <sys/types.h>
#include <sys/wait.h>
+// libseccomp
+#include <seccomp.h>
+
#include <pakfire/arch.h>
#include <pakfire/jail.h>
#include <pakfire/logging.h>
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,
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)