Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
12 | /* #define SECCOMP_DEBUG 1 */ | |
1d9d02fe | 13 | #define NR_SECCOMP_MODES 1 |
1da177e4 LT |
14 | |
15 | /* | |
16 | * Secure computing mode 1 allows only read/write/exit/sigreturn. | |
17 | * To be fully secure this must be combined with rlimit | |
18 | * to limit the stack allocations too. | |
19 | */ | |
20 | static int mode1_syscalls[] = { | |
21 | __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, | |
22 | 0, /* null terminated */ | |
23 | }; | |
24 | ||
25 | #ifdef TIF_32BIT | |
26 | static int mode1_syscalls_32[] = { | |
27 | __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, | |
28 | 0, /* null terminated */ | |
29 | }; | |
30 | #endif | |
31 | ||
32 | void __secure_computing(int this_syscall) | |
33 | { | |
34 | int mode = current->seccomp.mode; | |
35 | int * syscall; | |
36 | ||
37 | switch (mode) { | |
38 | case 1: | |
39 | syscall = mode1_syscalls; | |
40 | #ifdef TIF_32BIT | |
41 | if (test_thread_flag(TIF_32BIT)) | |
42 | syscall = mode1_syscalls_32; | |
43 | #endif | |
44 | do { | |
45 | if (*syscall == this_syscall) | |
46 | return; | |
47 | } while (*++syscall); | |
48 | break; | |
49 | default: | |
50 | BUG(); | |
51 | } | |
52 | ||
53 | #ifdef SECCOMP_DEBUG | |
54 | dump_stack(); | |
55 | #endif | |
56 | do_exit(SIGKILL); | |
57 | } | |
1d9d02fe AA |
58 | |
59 | long prctl_get_seccomp(void) | |
60 | { | |
61 | return current->seccomp.mode; | |
62 | } | |
63 | ||
64 | long prctl_set_seccomp(unsigned long seccomp_mode) | |
65 | { | |
66 | long ret; | |
67 | ||
68 | /* can set it only once to be even more secure */ | |
69 | ret = -EPERM; | |
70 | if (unlikely(current->seccomp.mode)) | |
71 | goto out; | |
72 | ||
73 | ret = -EINVAL; | |
74 | if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) { | |
75 | current->seccomp.mode = seccomp_mode; | |
76 | set_thread_flag(TIF_SECCOMP); | |
cf99abac AA |
77 | #ifdef TIF_NOTSC |
78 | disable_TSC(); | |
79 | #endif | |
1d9d02fe AA |
80 | ret = 0; |
81 | } | |
82 | ||
83 | out: | |
84 | return ret; | |
85 | } |