This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / kernel / seccomp.c
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
new file mode 100644 (file)
index 0000000..c3391b6
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * linux/kernel/seccomp.c
+ *
+ * Copyright 2004-2005  Andrea Arcangeli <andrea@cpushare.com>
+ *
+ * This defines a simple but solid secure-computing mode.
+ */
+
+#include <linux/seccomp.h>
+#include <linux/sched.h>
+
+/* #define SECCOMP_DEBUG 1 */
+
+/*
+ * Secure computing mode 1 allows only read/write/exit/sigreturn.
+ * To be fully secure this must be combined with rlimit
+ * to limit the stack allocations too.
+ */
+static int mode1_syscalls[] = {
+       __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
+       0, /* null terminated */
+};
+
+#ifdef TIF_32BIT
+static int mode1_syscalls_32[] = {
+       __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
+       0, /* null terminated */
+};
+#endif
+
+void __secure_computing(int this_syscall)
+{
+       int mode = current->seccomp.mode;
+       int * syscall;
+
+       switch (mode) {
+       case 1:
+               syscall = mode1_syscalls;
+#ifdef TIF_32BIT
+               if (test_thread_flag(TIF_32BIT))
+                       syscall = mode1_syscalls_32;
+#endif
+               do {
+                       if (*syscall == this_syscall)
+                               return;
+               } while (*++syscall);
+               break;
+       default:
+               BUG();
+       }
+
+#ifdef SECCOMP_DEBUG
+       dump_stack();
+#endif
+       do_exit(SIGKILL);
+}