]>
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> | |
5b101740 | 11 | #include <linux/compat.h> |
1da177e4 LT |
12 | |
13 | /* #define SECCOMP_DEBUG 1 */ | |
1d9d02fe | 14 | #define NR_SECCOMP_MODES 1 |
1da177e4 LT |
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 | ||
5b101740 | 26 | #ifdef CONFIG_COMPAT |
1da177e4 LT |
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; | |
5b101740 RM |
41 | #ifdef CONFIG_COMPAT |
42 | if (is_compat_task()) | |
1da177e4 LT |
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 | } | |
1d9d02fe AA |
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); | |
cf99abac AA |
78 | #ifdef TIF_NOTSC |
79 | disable_TSC(); | |
80 | #endif | |
1d9d02fe AA |
81 | ret = 0; |
82 | } | |
83 | ||
84 | out: | |
85 | return ret; | |
86 | } |