]>
Commit | Line | Data |
---|---|---|
57183d11 LP |
1 | /*** |
2 | This file is part of systemd. | |
3 | ||
4 | Copyright 2014 Lennart Poettering | |
5 | ||
6 | systemd is free software; you can redistribute it and/or modify it | |
7 | under the terms of the GNU Lesser General Public License as published by | |
8 | the Free Software Foundation; either version 2.1 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | systemd is distributed in the hope that it will be useful, but | |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public License | |
17 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
18 | ***/ | |
19 | ||
a8fbdf54 | 20 | #include <errno.h> |
57183d11 | 21 | #include <seccomp.h> |
a8fbdf54 | 22 | #include <stddef.h> |
d347d902 FS |
23 | #include <sys/prctl.h> |
24 | #include <linux/seccomp.h> | |
57183d11 | 25 | |
a8fbdf54 | 26 | #include "macro.h" |
cf0fbc49 | 27 | #include "seccomp-util.h" |
07630cea | 28 | #include "string-util.h" |
57183d11 LP |
29 | |
30 | const char* seccomp_arch_to_string(uint32_t c) { | |
31 | ||
32 | if (c == SCMP_ARCH_NATIVE) | |
33 | return "native"; | |
34 | if (c == SCMP_ARCH_X86) | |
35 | return "x86"; | |
36 | if (c == SCMP_ARCH_X86_64) | |
37 | return "x86-64"; | |
38 | if (c == SCMP_ARCH_X32) | |
39 | return "x32"; | |
40 | if (c == SCMP_ARCH_ARM) | |
41 | return "arm"; | |
42 | ||
43 | return NULL; | |
44 | } | |
45 | ||
46 | int seccomp_arch_from_string(const char *n, uint32_t *ret) { | |
47 | if (!n) | |
48 | return -EINVAL; | |
49 | ||
50 | assert(ret); | |
51 | ||
52 | if (streq(n, "native")) | |
53 | *ret = SCMP_ARCH_NATIVE; | |
54 | else if (streq(n, "x86")) | |
55 | *ret = SCMP_ARCH_X86; | |
56 | else if (streq(n, "x86-64")) | |
57 | *ret = SCMP_ARCH_X86_64; | |
58 | else if (streq(n, "x32")) | |
59 | *ret = SCMP_ARCH_X32; | |
60 | else if (streq(n, "arm")) | |
61 | *ret = SCMP_ARCH_ARM; | |
62 | else | |
63 | return -EINVAL; | |
64 | ||
65 | return 0; | |
66 | } | |
e9642be2 LP |
67 | |
68 | int seccomp_add_secondary_archs(scmp_filter_ctx *c) { | |
69 | ||
70 | #if defined(__i386__) || defined(__x86_64__) | |
71 | int r; | |
72 | ||
73 | /* Add in all possible secondary archs we are aware of that | |
74 | * this kernel might support. */ | |
75 | ||
76 | r = seccomp_arch_add(c, SCMP_ARCH_X86); | |
77 | if (r < 0 && r != -EEXIST) | |
78 | return r; | |
79 | ||
80 | r = seccomp_arch_add(c, SCMP_ARCH_X86_64); | |
81 | if (r < 0 && r != -EEXIST) | |
82 | return r; | |
83 | ||
84 | r = seccomp_arch_add(c, SCMP_ARCH_X32); | |
85 | if (r < 0 && r != -EEXIST) | |
86 | return r; | |
87 | ||
88 | #endif | |
89 | ||
90 | return 0; | |
91 | ||
92 | } | |
201c1cc2 | 93 | |
d347d902 FS |
94 | static bool is_basic_seccomp_available(void) { |
95 | int r; | |
96 | r = prctl(PR_GET_SECCOMP, 0, 0, 0, 0); | |
97 | return r >= 0; | |
98 | } | |
99 | ||
100 | static bool is_seccomp_filter_available(void) { | |
101 | int r; | |
102 | r = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0); | |
103 | return r < 0 && errno == EFAULT; | |
104 | } | |
105 | ||
83f12b27 | 106 | bool is_seccomp_available(void) { |
83f12b27 FS |
107 | static int cached_enabled = -1; |
108 | if (cached_enabled < 0) | |
d347d902 | 109 | cached_enabled = is_basic_seccomp_available() && is_seccomp_filter_available(); |
83f12b27 FS |
110 | return cached_enabled; |
111 | } | |
112 | ||
201c1cc2 TM |
113 | const SystemCallFilterSet syscall_filter_sets[] = { |
114 | { | |
115 | /* Clock */ | |
116 | .set_name = "@clock", | |
117 | .value = | |
118 | "adjtimex\0" | |
1f9ac68b LP |
119 | "clock_adjtime\0" |
120 | "clock_settime\0" | |
201c1cc2 | 121 | "settimeofday\0" |
1f9ac68b LP |
122 | "stime\0" |
123 | }, { | |
124 | /* CPU emulation calls */ | |
125 | .set_name = "@cpu-emulation", | |
126 | .value = | |
127 | "modify_ldt\0" | |
128 | "subpage_prot\0" | |
129 | "switch_endian\0" | |
130 | "vm86\0" | |
131 | "vm86old\0" | |
132 | }, { | |
133 | /* Debugging/Performance Monitoring/Tracing */ | |
134 | .set_name = "@debug", | |
135 | .value = | |
136 | "lookup_dcookie\0" | |
137 | "perf_event_open\0" | |
138 | "process_vm_readv\0" | |
139 | "process_vm_writev\0" | |
140 | "ptrace\0" | |
141 | "rtas\0" | |
142 | "s390_runtime_instr\0" | |
143 | "sys_debug_setcontext\0" | |
201c1cc2 TM |
144 | }, { |
145 | /* Default list */ | |
146 | .set_name = "@default", | |
147 | .value = | |
148 | "execve\0" | |
149 | "exit\0" | |
150 | "exit_group\0" | |
4a4485ae | 151 | "getrlimit\0" /* make sure processes can query stack size and such */ |
201c1cc2 TM |
152 | "rt_sigreturn\0" |
153 | "sigreturn\0" | |
154 | }, { | |
155 | /* Event loop use */ | |
156 | .set_name = "@io-event", | |
157 | .value = | |
158 | "_newselect\0" | |
159 | "epoll_create1\0" | |
160 | "epoll_create\0" | |
161 | "epoll_ctl\0" | |
162 | "epoll_ctl_old\0" | |
163 | "epoll_pwait\0" | |
164 | "epoll_wait\0" | |
165 | "epoll_wait_old\0" | |
166 | "eventfd2\0" | |
167 | "eventfd\0" | |
168 | "poll\0" | |
169 | "ppoll\0" | |
170 | "pselect6\0" | |
171 | "select\0" | |
172 | }, { | |
173 | /* Message queues, SYSV IPC or other IPC: unusual */ | |
174 | .set_name = "@ipc", | |
175 | .value = "ipc\0" | |
176 | "mq_getsetattr\0" | |
177 | "mq_notify\0" | |
178 | "mq_open\0" | |
179 | "mq_timedreceive\0" | |
180 | "mq_timedsend\0" | |
181 | "mq_unlink\0" | |
182 | "msgctl\0" | |
183 | "msgget\0" | |
184 | "msgrcv\0" | |
185 | "msgsnd\0" | |
186 | "process_vm_readv\0" | |
187 | "process_vm_writev\0" | |
188 | "semctl\0" | |
189 | "semget\0" | |
190 | "semop\0" | |
191 | "semtimedop\0" | |
192 | "shmat\0" | |
193 | "shmctl\0" | |
194 | "shmdt\0" | |
195 | "shmget\0" | |
1f9ac68b LP |
196 | }, { |
197 | /* Keyring */ | |
198 | .set_name = "@keyring", | |
199 | .value = | |
200 | "add_key\0" | |
201 | "keyctl\0" | |
202 | "request_key\0" | |
201c1cc2 TM |
203 | }, { |
204 | /* Kernel module control */ | |
205 | .set_name = "@module", | |
206 | .value = | |
201c1cc2 TM |
207 | "delete_module\0" |
208 | "finit_module\0" | |
209 | "init_module\0" | |
210 | }, { | |
211 | /* Mounting */ | |
212 | .set_name = "@mount", | |
213 | .value = | |
214 | "chroot\0" | |
215 | "mount\0" | |
216 | "oldumount\0" | |
217 | "pivot_root\0" | |
218 | "umount2\0" | |
219 | "umount\0" | |
220 | }, { | |
221 | /* Network or Unix socket IO, should not be needed if not network facing */ | |
222 | .set_name = "@network-io", | |
223 | .value = | |
224 | "accept4\0" | |
225 | "accept\0" | |
226 | "bind\0" | |
227 | "connect\0" | |
228 | "getpeername\0" | |
229 | "getsockname\0" | |
230 | "getsockopt\0" | |
231 | "listen\0" | |
232 | "recv\0" | |
233 | "recvfrom\0" | |
234 | "recvmmsg\0" | |
235 | "recvmsg\0" | |
236 | "send\0" | |
237 | "sendmmsg\0" | |
238 | "sendmsg\0" | |
239 | "sendto\0" | |
240 | "setsockopt\0" | |
241 | "shutdown\0" | |
242 | "socket\0" | |
243 | "socketcall\0" | |
244 | "socketpair\0" | |
245 | }, { | |
246 | /* Unusual, obsolete or unimplemented, some unknown even to libseccomp */ | |
247 | .set_name = "@obsolete", | |
248 | .value = | |
249 | "_sysctl\0" | |
250 | "afs_syscall\0" | |
251 | "break\0" | |
1f9ac68b | 252 | "create_module\0" |
201c1cc2 TM |
253 | "ftime\0" |
254 | "get_kernel_syms\0" | |
201c1cc2 TM |
255 | "getpmsg\0" |
256 | "gtty\0" | |
201c1cc2 | 257 | "lock\0" |
201c1cc2 | 258 | "mpx\0" |
201c1cc2 TM |
259 | "prof\0" |
260 | "profil\0" | |
201c1cc2 TM |
261 | "putpmsg\0" |
262 | "query_module\0" | |
201c1cc2 TM |
263 | "security\0" |
264 | "sgetmask\0" | |
265 | "ssetmask\0" | |
266 | "stty\0" | |
1f9ac68b | 267 | "sysfs\0" |
201c1cc2 TM |
268 | "tuxcall\0" |
269 | "ulimit\0" | |
270 | "uselib\0" | |
1f9ac68b | 271 | "ustat\0" |
201c1cc2 TM |
272 | "vserver\0" |
273 | }, { | |
274 | /* Nice grab-bag of all system calls which need superuser capabilities */ | |
275 | .set_name = "@privileged", | |
276 | .value = | |
277 | "@clock\0" | |
278 | "@module\0" | |
279 | "@raw-io\0" | |
280 | "acct\0" | |
281 | "bdflush\0" | |
282 | "bpf\0" | |
1f9ac68b | 283 | "capset\0" |
201c1cc2 TM |
284 | "chown32\0" |
285 | "chown\0" | |
286 | "chroot\0" | |
287 | "fchown32\0" | |
288 | "fchown\0" | |
289 | "fchownat\0" | |
290 | "kexec_file_load\0" | |
291 | "kexec_load\0" | |
292 | "lchown32\0" | |
293 | "lchown\0" | |
294 | "nfsservctl\0" | |
295 | "pivot_root\0" | |
296 | "quotactl\0" | |
297 | "reboot\0" | |
298 | "setdomainname\0" | |
299 | "setfsuid32\0" | |
300 | "setfsuid\0" | |
301 | "setgroups32\0" | |
302 | "setgroups\0" | |
303 | "sethostname\0" | |
304 | "setresuid32\0" | |
305 | "setresuid\0" | |
306 | "setreuid32\0" | |
307 | "setreuid\0" | |
308 | "setuid32\0" | |
309 | "setuid\0" | |
201c1cc2 TM |
310 | "swapoff\0" |
311 | "swapon\0" | |
312 | "sysctl\0" | |
313 | "vhangup\0" | |
314 | }, { | |
315 | /* Process control, execution, namespaces */ | |
316 | .set_name = "@process", | |
317 | .value = | |
318 | "arch_prctl\0" | |
319 | "clone\0" | |
320 | "execve\0" | |
321 | "execveat\0" | |
322 | "fork\0" | |
323 | "kill\0" | |
324 | "prctl\0" | |
325 | "setns\0" | |
326 | "tgkill\0" | |
327 | "tkill\0" | |
328 | "unshare\0" | |
329 | "vfork\0" | |
330 | }, { | |
331 | /* Raw I/O ports */ | |
332 | .set_name = "@raw-io", | |
333 | .value = | |
334 | "ioperm\0" | |
335 | "iopl\0" | |
1f9ac68b | 336 | "pciconfig_iobase\0" |
201c1cc2 TM |
337 | "pciconfig_read\0" |
338 | "pciconfig_write\0" | |
339 | "s390_pci_mmio_read\0" | |
340 | "s390_pci_mmio_write\0" | |
341 | }, { | |
342 | .set_name = NULL, | |
343 | .value = NULL | |
344 | } | |
345 | }; |