]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/seccomp-util.c
seccomp: also detect if seccomp filtering is enabled
[thirdparty/systemd.git] / src / shared / seccomp-util.c
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
20 #include <errno.h>
21 #include <seccomp.h>
22 #include <stddef.h>
23 #include <sys/prctl.h>
24 #include <linux/seccomp.h>
25
26 #include "macro.h"
27 #include "seccomp-util.h"
28 #include "string-util.h"
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 }
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 }
93
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
106 bool is_seccomp_available(void) {
107 static int cached_enabled = -1;
108 if (cached_enabled < 0)
109 cached_enabled = is_basic_seccomp_available() && is_seccomp_filter_available();
110 return cached_enabled;
111 }
112
113 const SystemCallFilterSet syscall_filter_sets[] = {
114 {
115 /* Clock */
116 .set_name = "@clock",
117 .value =
118 "adjtimex\0"
119 "clock_adjtime\0"
120 "clock_settime\0"
121 "settimeofday\0"
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"
144 }, {
145 /* Default list */
146 .set_name = "@default",
147 .value =
148 "execve\0"
149 "exit\0"
150 "exit_group\0"
151 "getrlimit\0" /* make sure processes can query stack size and such */
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"
196 }, {
197 /* Keyring */
198 .set_name = "@keyring",
199 .value =
200 "add_key\0"
201 "keyctl\0"
202 "request_key\0"
203 }, {
204 /* Kernel module control */
205 .set_name = "@module",
206 .value =
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"
252 "create_module\0"
253 "ftime\0"
254 "get_kernel_syms\0"
255 "getpmsg\0"
256 "gtty\0"
257 "lock\0"
258 "mpx\0"
259 "prof\0"
260 "profil\0"
261 "putpmsg\0"
262 "query_module\0"
263 "security\0"
264 "sgetmask\0"
265 "ssetmask\0"
266 "stty\0"
267 "sysfs\0"
268 "tuxcall\0"
269 "ulimit\0"
270 "uselib\0"
271 "ustat\0"
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"
283 "capset\0"
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"
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"
336 "pciconfig_iobase\0"
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 };