1 /* 2 * linux/kernel/seccomp.c 3 * 4 * Copyright 2004-2005 Andrea Arcangeli <andrea@cpushare.com> 5 * 6 * This defines a simple but solid secure-computing mode. 7 */ 8 9 #include <linux/seccomp.h> 10 #include <linux/sched.h> 11 #include <linux/compat.h> 12 13 /* #define SECCOMP_DEBUG 1 */ 14 #define NR_SECCOMP_MODES 1 15 16 /* 17 * Secure computing mode 1 allows only read/write/exit/sigreturn. 18 * To be fully secure this must be combined with rlimit 19 * to limit the stack allocations too. 20 */ 21 static int mode1_syscalls[] = { 22 __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, 23 0, /* null terminated */ 24 }; 25 26 #ifdef CONFIG_COMPAT 27 static int mode1_syscalls_32[] = { 28 __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, 29 0, /* null terminated */ 30 }; 31 #endif 32 33 void __secure_computing(int this_syscall) 34 { 35 int mode = current->seccomp.mode; 36 int * syscall; 37 38 switch (mode) { 39 case 1: 40 syscall = mode1_syscalls; 41 #ifdef CONFIG_COMPAT 42 if (is_compat_task()) 43 syscall = mode1_syscalls_32; 44 #endif 45 do { 46 if (*syscall == this_syscall) 47 return; 48 } while (*++syscall); 49 break; 50 default: 51 BUG(); 52 } 53 54 #ifdef SECCOMP_DEBUG 55 dump_stack(); 56 #endif 57 do_exit(SIGKILL); 58 } 59 60 long prctl_get_seccomp(void) 61 { 62 return current->seccomp.mode; 63 } 64 65 long prctl_set_seccomp(unsigned long seccomp_mode) 66 { 67 long ret; 68 69 /* can set it only once to be even more secure */ 70 ret = -EPERM; 71 if (unlikely(current->seccomp.mode)) 72 goto out; 73 74 ret = -EINVAL; 75 if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) { 76 current->seccomp.mode = seccomp_mode; 77 set_thread_flag(TIF_SECCOMP); 78 #ifdef TIF_NOTSC 79 disable_TSC(); 80 #endif 81 ret = 0; 82 } 83 84 out: 85 return ret; 86 } 87