diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/init_task.h | 12 | ||||
| -rw-r--r-- | include/linux/prctl.h | 7 | ||||
| -rw-r--r-- | include/linux/sched.h | 2 | ||||
| -rw-r--r-- | include/linux/seccomp.h | 119 |
4 files changed, 136 insertions, 4 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 580f70c0239..56deaf25371 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
| @@ -126,6 +126,17 @@ extern struct cred init_cred; | |||
| 126 | # define INIT_PERF_EVENTS(tsk) | 126 | # define INIT_PERF_EVENTS(tsk) |
| 127 | #endif | 127 | #endif |
| 128 | 128 | ||
| 129 | #ifdef CONFIG_SECCOMP_FILTER | ||
| 130 | # define INIT_SECCOMP_FILTER(tsk) \ | ||
| 131 | .seccomp = { \ | ||
| 132 | .filters_guard = \ | ||
| 133 | __MUTEX_INITIALIZER(tsk.seccomp.filters_guard), \ | ||
| 134 | }, | ||
| 135 | #else | ||
| 136 | # define INIT_SECCOMP_FILTER(tsk) | ||
| 137 | #endif | ||
| 138 | |||
| 139 | |||
| 129 | /* | 140 | /* |
| 130 | * INIT_TASK is used to set up the first task table, touch at | 141 | * INIT_TASK is used to set up the first task table, touch at |
| 131 | * your own risk!. Base=0, limit=0x1fffff (=2MB) | 142 | * your own risk!. Base=0, limit=0x1fffff (=2MB) |
| @@ -188,6 +199,7 @@ extern struct cred init_cred; | |||
| 188 | .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \ | 199 | .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \ |
| 189 | INIT_IDS \ | 200 | INIT_IDS \ |
| 190 | INIT_PERF_EVENTS(tsk) \ | 201 | INIT_PERF_EVENTS(tsk) \ |
| 202 | INIT_SECCOMP_FILTER(tsk) \ | ||
| 191 | INIT_TRACE_IRQFLAGS \ | 203 | INIT_TRACE_IRQFLAGS \ |
| 192 | INIT_LOCKDEP \ | 204 | INIT_LOCKDEP \ |
| 193 | INIT_FTRACE_GRAPH \ | 205 | INIT_FTRACE_GRAPH \ |
diff --git a/include/linux/prctl.h b/include/linux/prctl.h index da7837bbd2c..74deeb717c6 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h | |||
| @@ -64,6 +64,13 @@ | |||
| 64 | #define PR_GET_SECCOMP 21 | 64 | #define PR_GET_SECCOMP 21 |
| 65 | #define PR_SET_SECCOMP 22 | 65 | #define PR_SET_SECCOMP 22 |
| 66 | 66 | ||
| 67 | /* Get/set process seccomp filters */ | ||
| 68 | #define PR_GET_SECCOMP_FILTER 35 | ||
| 69 | #define PR_SET_SECCOMP_FILTER 36 | ||
| 70 | #define PR_CLEAR_SECCOMP_FILTER 37 | ||
| 71 | # define PR_SECCOMP_FILTER_SYSCALL 0 | ||
| 72 | # define PR_SECCOMP_FILTER_EVENT 1 | ||
| 73 | |||
| 67 | /* Get/set the capability bounding set (as per security/commoncap.c) */ | 74 | /* Get/set the capability bounding set (as per security/commoncap.c) */ |
| 68 | #define PR_CAPBSET_READ 23 | 75 | #define PR_CAPBSET_READ 23 |
| 69 | #define PR_CAPBSET_DROP 24 | 76 | #define PR_CAPBSET_DROP 24 |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 7badc5d9f07..9cdfbf4a97a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -1411,7 +1411,7 @@ struct task_struct { | |||
| 1411 | uid_t loginuid; | 1411 | uid_t loginuid; |
| 1412 | unsigned int sessionid; | 1412 | unsigned int sessionid; |
| 1413 | #endif | 1413 | #endif |
| 1414 | seccomp_t seccomp; | 1414 | struct seccomp_struct seccomp; |
| 1415 | 1415 | ||
| 1416 | /* Thread group tracking */ | 1416 | /* Thread group tracking */ |
| 1417 | u32 parent_exec_id; | 1417 | u32 parent_exec_id; |
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 167c33361d9..f81a9827334 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h | |||
| @@ -1,13 +1,35 @@ | |||
| 1 | #ifndef _LINUX_SECCOMP_H | 1 | #ifndef _LINUX_SECCOMP_H |
| 2 | #define _LINUX_SECCOMP_H | 2 | #define _LINUX_SECCOMP_H |
| 3 | 3 | ||
| 4 | struct seq_file; | ||
| 4 | 5 | ||
| 5 | #ifdef CONFIG_SECCOMP | 6 | #ifdef CONFIG_SECCOMP |
| 6 | 7 | ||
| 8 | #include <linux/errno.h> | ||
| 7 | #include <linux/thread_info.h> | 9 | #include <linux/thread_info.h> |
| 10 | #include <linux/types.h> | ||
| 11 | #include <linux/mutex.h> | ||
| 8 | #include <asm/seccomp.h> | 12 | #include <asm/seccomp.h> |
| 9 | 13 | ||
| 10 | typedef struct { int mode; } seccomp_t; | 14 | struct seccomp_filters; |
| 15 | /** | ||
| 16 | * struct seccomp_struct - the state of a seccomp'ed process | ||
| 17 | * | ||
| 18 | * @mode: | ||
| 19 | * if this is 1, the process is under standard seccomp rules | ||
| 20 | * is 13, the process is only allowed to make system calls where | ||
| 21 | * associated filters evaluate successfully. | ||
| 22 | * @filters: Metadata for filters if using CONFIG_SECCOMP_FILTER. | ||
| 23 | * @filters assignment and use should always be guarded by | ||
| 24 | * @filters_guard. | ||
| 25 | */ | ||
| 26 | struct seccomp_struct { | ||
| 27 | int mode; | ||
| 28 | #ifdef CONFIG_SECCOMP_FILTER | ||
| 29 | struct mutex filters_guard; | ||
| 30 | struct seccomp_filters *filters; | ||
| 31 | #endif | ||
| 32 | }; | ||
| 11 | 33 | ||
| 12 | extern void __secure_computing(int); | 34 | extern void __secure_computing(int); |
| 13 | static inline void secure_computing(int this_syscall) | 35 | static inline void secure_computing(int this_syscall) |
| @@ -23,8 +45,7 @@ extern long prctl_set_seccomp(unsigned long); | |||
| 23 | 45 | ||
| 24 | #include <linux/errno.h> | 46 | #include <linux/errno.h> |
| 25 | 47 | ||
| 26 | typedef struct { } seccomp_t; | 48 | struct seccomp_struct { }; |
| 27 | |||
| 28 | #define secure_computing(x) do { } while (0) | 49 | #define secure_computing(x) do { } while (0) |
| 29 | 50 | ||
| 30 | static inline long prctl_get_seccomp(void) | 51 | static inline long prctl_get_seccomp(void) |
| @@ -39,4 +60,96 @@ static inline long prctl_set_seccomp(unsigned long arg2) | |||
| 39 | 60 | ||
| 40 | #endif /* CONFIG_SECCOMP */ | 61 | #endif /* CONFIG_SECCOMP */ |
| 41 | 62 | ||
| 63 | #ifdef CONFIG_SECCOMP_FILTER | ||
| 64 | |||
| 65 | #define seccomp_filter_init_task(_tsk) do { \ | ||
| 66 | mutex_init(&(_tsk)->seccomp.filters_guard); \ | ||
| 67 | (_tsk)->seccomp.filters = NULL; \ | ||
| 68 | } while (0); | ||
| 69 | |||
| 70 | /* Do nothing unless seccomp filtering is active. If not, the execve boundary | ||
| 71 | * can not be cleanly enforced and preset filters may leak across execve calls. | ||
| 72 | */ | ||
| 73 | #define seccomp_filter_fork(_tsk, _orig) do { \ | ||
| 74 | if ((_tsk)->seccomp.mode) { \ | ||
| 75 | (_tsk)->seccomp.mode = (_orig)->seccomp.mode; \ | ||
| 76 | mutex_lock(&(_orig)->seccomp.filters_guard); \ | ||
| 77 | (_tsk)->seccomp.filters = \ | ||
| 78 | get_seccomp_filters((_orig)->seccomp.filters); \ | ||
| 79 | mutex_unlock(&(_orig)->seccomp.filters_guard); \ | ||
| 80 | } \ | ||
| 81 | } while (0); | ||
| 82 | |||
| 83 | /* No locking is needed here because the task_struct will | ||
| 84 | * have no parallel consumers. | ||
| 85 | */ | ||
| 86 | #define seccomp_filter_free_task(_tsk) do { \ | ||
| 87 | put_seccomp_filters((_tsk)->seccomp.filters); \ | ||
| 88 | } while (0); | ||
| 89 | |||
| 90 | extern int seccomp_show_filters(struct seccomp_filters *filters, | ||
| 91 | struct seq_file *); | ||
| 92 | extern long seccomp_set_filter(int, char *); | ||
| 93 | extern long seccomp_clear_filter(int); | ||
| 94 | extern long seccomp_get_filter(int, char *, unsigned long); | ||
| 95 | |||
| 96 | extern long prctl_set_seccomp_filter(unsigned long, unsigned long, | ||
| 97 | char __user *); | ||
| 98 | extern long prctl_get_seccomp_filter(unsigned long, unsigned long, | ||
| 99 | char __user *, unsigned long); | ||
| 100 | extern long prctl_clear_seccomp_filter(unsigned long, unsigned long); | ||
| 101 | |||
| 102 | extern struct seccomp_filters *get_seccomp_filters(struct seccomp_filters *); | ||
| 103 | extern void put_seccomp_filters(struct seccomp_filters *); | ||
| 104 | |||
| 105 | extern int seccomp_test_filters(int); | ||
| 106 | extern void seccomp_filter_log_failure(int); | ||
| 107 | |||
| 108 | #else /* CONFIG_SECCOMP_FILTER */ | ||
| 109 | |||
| 110 | struct seccomp_filters { }; | ||
| 111 | #define seccomp_filter_init_task(_tsk) do { } while (0); | ||
| 112 | #define seccomp_filter_fork(_tsk, _orig) do { } while (0); | ||
| 113 | #define seccomp_filter_free_task(_tsk) do { } while (0); | ||
| 114 | |||
| 115 | static inline int seccomp_show_filters(struct seccomp_filters *filters, | ||
| 116 | struct seq_file *m) | ||
| 117 | { | ||
| 118 | return -ENOSYS; | ||
| 119 | } | ||
| 120 | |||
| 121 | static inline long seccomp_set_filter(int syscall_nr, char *filter) | ||
| 122 | { | ||
| 123 | return -ENOSYS; | ||
| 124 | } | ||
| 125 | |||
| 126 | static inline long seccomp_clear_filter(int syscall_nr) | ||
| 127 | { | ||
| 128 | return -ENOSYS; | ||
| 129 | } | ||
| 130 | |||
| 131 | static inline long seccomp_get_filter(int syscall_nr, | ||
| 132 | char *buf, unsigned long available) | ||
| 133 | { | ||
| 134 | return -ENOSYS; | ||
| 135 | } | ||
| 136 | |||
| 137 | static inline long prctl_set_seccomp_filter(unsigned long a2, unsigned long a3, | ||
| 138 | char __user *a4) | ||
| 139 | { | ||
| 140 | return -ENOSYS; | ||
| 141 | } | ||
| 142 | |||
| 143 | static inline long prctl_clear_seccomp_filter(unsigned long a2, | ||
| 144 | unsigned long a3) | ||
| 145 | { | ||
| 146 | return -ENOSYS; | ||
| 147 | } | ||
| 148 | |||
| 149 | static inline long prctl_get_seccomp_filter(unsigned long a2, unsigned long a3, | ||
| 150 | char __user *a4, unsigned long a5) | ||
| 151 | { | ||
| 152 | return -ENOSYS; | ||
| 153 | } | ||
| 154 | #endif /* CONFIG_SECCOMP_FILTER */ | ||
| 42 | #endif /* _LINUX_SECCOMP_H */ | 155 | #endif /* _LINUX_SECCOMP_H */ |
