Skip to content

Instantly share code, notes, and snippets.

@aszlig
Last active October 29, 2016 01:05
Show Gist options
  • Save aszlig/69c3d7cf92a2c05ee1230857c2734848 to your computer and use it in GitHub Desktop.
Save aszlig/69c3d7cf92a2c05ee1230857c2734848 to your computer and use it in GitHub Desktop.
with import <nixpkgs> {};
runCommandCC "nix-seccomp-userns" {} ''
gcc -Wall -o "$out" -xc - <<EOF
#define _GNU_SOURCE
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
#include <sys/prctl.h>
#include <stddef.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sched.h>
#include <stdlib.h>
static struct sock_filter filter[] = {
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_chown, 4, 0),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_fchown, 3, 0),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_fchownat, 2, 0),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_lchown, 1, 0),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO),
};
#define errout(msg) { perror(msg); return 1; }
#define write_map(what, ...) \
FILE *what##handle = fopen("/proc/self/" #what, "w"); \
if (what##handle == NULL) errout("fopen(" #what ")"); \
if (fprintf(what##handle, __VA_ARGS__) < 0) errout("write map"); \
if (fclose(what##handle) == EOF) errout("close map");
int main(void) {
int uid = getuid();
int gid = getgid();
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
.filter = filter,
};
if (unshare(CLONE_NEWUSER) == -1)
errout("unshare(CLONE_NEWUSER)");
write_map(setgroups, "deny");
write_map(uid_map, "0 %d 1", uid);
write_map(gid_map, "0 %d 1", gid);
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1)
errout("prctl(SECCOMP_BPF)");
return system(getenv("SHELL") ?: "/bin/sh");
}
EOF
''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment