#include <sys/wait.h>
#include <unistd.h>
+// libseccomp
+#include <seccomp.h>
+
#include <pakfire/arch.h>
#include <pakfire/cgroup.h>
#include <pakfire/execute.h>
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;
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) {