Permalink
Browse files

Add support for seccomp-filter on Linux. Based on OpenSSH portable. I…

…t 'appears' to work.
  • Loading branch information...
1 parent cba2ef5 commit 612a76f47d879d8c7cc5791b49a3704b54391e05 @brynet committed Apr 30, 2015
Showing with 112 additions and 0 deletions.
  1. +4 −0 Makefile
  2. +108 −0 sandbox.c
View
@@ -47,3 +47,7 @@ $(PROG): $(OBJS)
clean:
rm -f $(OBJS) $(PROG)
+
+#syscall-linux.txt:
+# echo "#include <sys/syscall.h>" | cpp -dM | grep '^#define __NR_' | \
+# LC_ALL=C sed -r -n -e 's/^\#define[ \t]+__NR_([a-z0-9_]+)[ \t]+([0-9]+)(.*)/ [\2] = "\1",/p' >> $@ ;\
View
@@ -23,6 +23,41 @@
#ifdef __OpenBSD__
#include <dev/systrace.h>
+#elif __linux
+#include <sys/resource.h>
+#include <sys/prctl.h>
+
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+
+#include <stddef.h> /* offsetof */
+
+/* Linux seccomp_filter sandbox */
+#define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL
+
+/* Use a signal handler to emit violations when debugging */
+#ifdef SANDBOX_DEBUG
+#undef SECCOMP_FILTER_FAIL
+#define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
+#endif
+
+/* XXX: */
+#ifndef SECCOMP_AUDIT_ARCH
+#if defined __i386__
+#define SECCOMP_AUDIT_ARCH AUDIT_ARCH_I386
+#elif defined __x86_64__ || defined __amd64__
+#define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64
+#endif
+#endif /* SECCOMP_AUDIT_ARCH */
+
+/* Simple helpers to avoid manual errors (but larger BPF programs). */
+#define SC_DENY(_nr, _errno) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno))
+#define SC_ALLOW(_nr) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#endif
#include <errno.h>
@@ -75,6 +110,71 @@ sandbox_find(int syscallnum)
}
return (SYSTR_POLICY_KILL);
}
+#elif __linux
+/* Syscall filtering set for preauth. */
+static const struct sock_filter preauth_insns[] = {
+ /* Ensure the syscall arch convention is as expected. */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+ offsetof(struct seccomp_data, arch)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
+ /* Load the syscall number for checking. */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+ offsetof(struct seccomp_data, nr)),
+ SC_DENY(open, EACCES),
+ SC_ALLOW(brk),
+ SC_ALLOW(close),
+ SC_ALLOW(exit_group),
+ SC_ALLOW(fstat),
+ SC_ALLOW(getpid),
+ SC_ALLOW(kill),
+ SC_ALLOW(mmap),
+ SC_ALLOW(munmap),
+ SC_ALLOW(read),
+ SC_ALLOW(recvmsg),
+ SC_ALLOW(sendmsg),
+ SC_ALLOW(write),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
+};
+
+static const struct sock_fprog preauth_program = {
+ .len = (unsigned short)(sizeof(preauth_insns)/sizeof(preauth_insns[0])),
+ .filter = (struct sock_filter *)preauth_insns,
+};
+
+#ifdef SANDBOX_DEBUG
+static void
+sandbox_violation(int signum, siginfo_t *info, void *void_context)
+{
+ char msg[256];
+
+ snprintf(msg, sizeof(msg),
+ "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)\n",
+ __func__, info->si_arch, info->si_syscall, info->si_call_addr);
+ write(STDOUT_FILENO, msg, strlen(msg));
+ _exit(1);
+}
+#endif /* SANDBOX_DEBUG */
+
+static void
+sandbox_child_debugging(void)
+{
+#ifdef SANDBOX_DEBUG
+ struct sigaction act;
+ sigset_t mask;
+
+ memset(&act, 0, sizeof(act));
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGSYS);
+
+ act.sa_sigaction = &sandbox_violation;
+ act.sa_flags = SA_SIGINFO;
+ if (sigaction(SIGSYS, &act, NULL) == -1)
+ err(1, "sigaction(SIGSYS)");
+ if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
+ err(1, "sigprocmask(SIGSYS)");
+#endif /* SANDBOX_DEBUG */
+}
#endif /* __OpenBSD__ */
static int
@@ -103,6 +203,14 @@ sandbox_child(const char *user)
err(1, "setresgid");
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0)
err(1, "setresuid");
+#ifdef __linux
+ sandbox_child_debugging();
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
+ err(1, "prctl(PR_SET_NO_NEW_PRIVS)");
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER,
+ &preauth_program) == -1)
+ err(1, "prctl(PR_SET_SECCOMP/SECCOMP_MODE_FILTER)");
+#endif
}
if (kill(getpid(), SIGSTOP) != 0)

0 comments on commit 612a76f

Please sign in to comment.