]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/seccomp-util.c
seccomp: also detect if seccomp filtering is enabled
[thirdparty/systemd.git] / src / shared / seccomp-util.c
CommitLineData
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
30const 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
46int 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
68int 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
94static 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
100static 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 106bool 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
113const 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};