]> git.proxmox.com Git - systemd.git/blob - src/test/test-seccomp.c
New upstream version 249~rc1
[systemd.git] / src / test / test-seccomp.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <fcntl.h>
4 #include <poll.h>
5 #include <stdlib.h>
6 #include <sys/eventfd.h>
7 #include <sys/mman.h>
8 #include <sys/personality.h>
9 #include <sys/shm.h>
10 #include <sys/syscall.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13 #if HAVE_VALGRIND_VALGRIND_H
14 #include <valgrind/valgrind.h>
15 #endif
16
17 #include "alloc-util.h"
18 #include "capability-util.h"
19 #include "fd-util.h"
20 #include "fileio.h"
21 #include "macro.h"
22 #include "memory-util.h"
23 #include "missing_sched.h"
24 #include "nsflags.h"
25 #include "nulstr-util.h"
26 #include "process-util.h"
27 #include "raw-clone.h"
28 #include "rm-rf.h"
29 #include "seccomp-util.h"
30 #include "set.h"
31 #include "string-util.h"
32 #include "tests.h"
33 #include "tmpfile-util.h"
34 #include "virt.h"
35
36 /* __NR_socket may be invalid due to libseccomp */
37 #if !defined(__NR_socket) || __NR_socket < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__) || defined(__powerpc__)
38 /* On these archs, socket() is implemented via the socketcall() syscall multiplexer,
39 * and we can't restrict it hence via seccomp. */
40 # define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1
41 #else
42 # define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0
43 #endif
44
45 static bool have_seccomp_privs(void) {
46 return geteuid() == 0 && have_effective_cap(CAP_SYS_ADMIN) > 0; /* If we are root but CAP_SYS_ADMIN we can't do caps (unless we also do NNP) */
47 }
48
49 static void test_parse_syscall_and_errno(void) {
50 _cleanup_free_ char *n = NULL;
51 int e;
52
53 assert_se(parse_syscall_and_errno("uname:EILSEQ", &n, &e) >= 0);
54 assert_se(streq(n, "uname"));
55 assert_se(e == errno_from_name("EILSEQ") && e >= 0);
56 n = mfree(n);
57
58 assert_se(parse_syscall_and_errno("uname:EINVAL", &n, &e) >= 0);
59 assert_se(streq(n, "uname"));
60 assert_se(e == errno_from_name("EINVAL") && e >= 0);
61 n = mfree(n);
62
63 assert_se(parse_syscall_and_errno("@sync:4095", &n, &e) >= 0);
64 assert_se(streq(n, "@sync"));
65 assert_se(e == 4095);
66 n = mfree(n);
67
68 /* If errno is omitted, then e is set to -1 */
69 assert_se(parse_syscall_and_errno("mount", &n, &e) >= 0);
70 assert_se(streq(n, "mount"));
71 assert_se(e == -1);
72 n = mfree(n);
73
74 /* parse_syscall_and_errno() does not check the syscall name is valid or not. */
75 assert_se(parse_syscall_and_errno("hoge:255", &n, &e) >= 0);
76 assert_se(streq(n, "hoge"));
77 assert_se(e == 255);
78 n = mfree(n);
79
80 /* 0 is also a valid errno. */
81 assert_se(parse_syscall_and_errno("hoge:0", &n, &e) >= 0);
82 assert_se(streq(n, "hoge"));
83 assert_se(e == 0);
84 n = mfree(n);
85
86 assert_se(parse_syscall_and_errno("hoge:kill", &n, &e) >= 0);
87 assert_se(streq(n, "hoge"));
88 assert_se(e == SECCOMP_ERROR_NUMBER_KILL);
89 n = mfree(n);
90
91 /* The function checks the syscall name is empty or not. */
92 assert_se(parse_syscall_and_errno("", &n, &e) == -EINVAL);
93 assert_se(parse_syscall_and_errno(":255", &n, &e) == -EINVAL);
94
95 /* errno must be a valid errno name or number between 0 and ERRNO_MAX == 4095, or "kill" */
96 assert_se(parse_syscall_and_errno("hoge:4096", &n, &e) == -ERANGE);
97 assert_se(parse_syscall_and_errno("hoge:-3", &n, &e) == -ERANGE);
98 assert_se(parse_syscall_and_errno("hoge:12.3", &n, &e) == -EINVAL);
99 assert_se(parse_syscall_and_errno("hoge:123junk", &n, &e) == -EINVAL);
100 assert_se(parse_syscall_and_errno("hoge:junk123", &n, &e) == -EINVAL);
101 assert_se(parse_syscall_and_errno("hoge:255:EILSEQ", &n, &e) == -EINVAL);
102 assert_se(parse_syscall_and_errno("hoge:-EINVAL", &n, &e) == -EINVAL);
103 assert_se(parse_syscall_and_errno("hoge:EINVALaaa", &n, &e) == -EINVAL);
104 assert_se(parse_syscall_and_errno("hoge:", &n, &e) == -EINVAL);
105 }
106
107 static void test_seccomp_arch_to_string(void) {
108 uint32_t a, b;
109 const char *name;
110
111 log_info("/* %s */", __func__);
112
113 a = seccomp_arch_native();
114 assert_se(a > 0);
115 name = seccomp_arch_to_string(a);
116 assert_se(name);
117 assert_se(seccomp_arch_from_string(name, &b) >= 0);
118 assert_se(a == b);
119 }
120
121 static void test_architecture_table(void) {
122 const char *n, *n2;
123
124 log_info("/* %s */", __func__);
125
126 NULSTR_FOREACH(n,
127 "native\0"
128 "x86\0"
129 "x86-64\0"
130 "x32\0"
131 "arm\0"
132 "arm64\0"
133 "mips\0"
134 "mips64\0"
135 "mips64-n32\0"
136 "mips-le\0"
137 "mips64-le\0"
138 "mips64-le-n32\0"
139 "ppc\0"
140 "ppc64\0"
141 "ppc64-le\0"
142 #ifdef SCMP_ARCH_RISCV64
143 "riscv64\0"
144 #endif
145 "s390\0"
146 "s390x\0") {
147 uint32_t c;
148
149 assert_se(seccomp_arch_from_string(n, &c) >= 0);
150 n2 = seccomp_arch_to_string(c);
151 log_info("seccomp-arch: %s → 0x%"PRIx32" → %s", n, c, n2);
152 assert_se(streq_ptr(n, n2));
153 }
154 }
155
156 static void test_syscall_filter_set_find(void) {
157 log_info("/* %s */", __func__);
158
159 assert_se(!syscall_filter_set_find(NULL));
160 assert_se(!syscall_filter_set_find(""));
161 assert_se(!syscall_filter_set_find("quux"));
162 assert_se(!syscall_filter_set_find("@quux"));
163
164 assert_se(syscall_filter_set_find("@clock") == syscall_filter_sets + SYSCALL_FILTER_SET_CLOCK);
165 assert_se(syscall_filter_set_find("@default") == syscall_filter_sets + SYSCALL_FILTER_SET_DEFAULT);
166 assert_se(syscall_filter_set_find("@raw-io") == syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO);
167 }
168
169 static void test_filter_sets(void) {
170 log_info("/* %s */", __func__);
171
172 if (!is_seccomp_available()) {
173 log_notice("Seccomp not available, skipping %s", __func__);
174 return;
175 }
176 if (!have_seccomp_privs()) {
177 log_notice("Not privileged, skipping %s", __func__);
178 return;
179 }
180
181 for (unsigned i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
182 pid_t pid;
183
184 #if HAVE_VALGRIND_VALGRIND_H
185 if (RUNNING_ON_VALGRIND && IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_BASIC_IO, SYSCALL_FILTER_SET_SIGNAL)) {
186 /* valgrind at least requires rt_sigprocmask(), read(), write(). */
187 log_info("Running on valgrind, skipping %s", syscall_filter_sets[i].name);
188 continue;
189 }
190 #endif
191 #if HAS_FEATURE_ADDRESS_SANITIZER
192 if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_BASIC_IO, SYSCALL_FILTER_SET_SIGNAL)) {
193 /* ASAN at least requires sigaltstack(), read(), write(). */
194 log_info("Running on address sanitizer, skipping %s", syscall_filter_sets[i].name);
195 continue;
196 }
197 #endif
198
199 log_info("Testing %s", syscall_filter_sets[i].name);
200
201 pid = fork();
202 assert_se(pid >= 0);
203
204 if (pid == 0) { /* Child? */
205 int fd, r;
206
207 /* If we look at the default set (or one that includes it), allow-list instead of deny-list */
208 if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT,
209 SYSCALL_FILTER_SET_SYSTEM_SERVICE,
210 SYSCALL_FILTER_SET_KNOWN))
211 r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true);
212 else
213 r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true);
214 if (r < 0)
215 _exit(EXIT_FAILURE);
216
217 /* Test the sycall filter with one random system call */
218 fd = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC);
219 if (IN_SET(i, SYSCALL_FILTER_SET_IO_EVENT, SYSCALL_FILTER_SET_DEFAULT))
220 assert_se(fd < 0 && errno == EUCLEAN);
221 else {
222 assert_se(fd >= 0);
223 safe_close(fd);
224 }
225
226 _exit(EXIT_SUCCESS);
227 }
228
229 assert_se(wait_for_terminate_and_check(syscall_filter_sets[i].name, pid, WAIT_LOG) == EXIT_SUCCESS);
230 }
231 }
232
233 static void test_filter_sets_ordered(void) {
234 log_info("/* %s */", __func__);
235
236 /* Ensure "@default" always remains at the beginning of the list */
237 assert_se(SYSCALL_FILTER_SET_DEFAULT == 0);
238 assert_se(streq(syscall_filter_sets[0].name, "@default"));
239
240 /* Ensure "@known" always remains at the end of the list */
241 assert_se(SYSCALL_FILTER_SET_KNOWN == _SYSCALL_FILTER_SET_MAX - 1);
242 assert_se(streq(syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].name, "@known"));
243
244 for (size_t i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
245 const char *k, *p = NULL;
246
247 /* Make sure each group has a description */
248 assert_se(!isempty(syscall_filter_sets[0].help));
249
250 /* Make sure the groups are ordered alphabetically, except for the first and last entries */
251 assert_se(i < 2 || i == _SYSCALL_FILTER_SET_MAX - 1 ||
252 strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0);
253
254 NULSTR_FOREACH(k, syscall_filter_sets[i].value) {
255
256 /* Ensure each syscall list is in itself ordered, but groups before names */
257 assert_se(!p ||
258 (*p == '@' && *k != '@') ||
259 (((*p == '@' && *k == '@') ||
260 (*p != '@' && *k != '@')) &&
261 strcmp(p, k) < 0));
262
263 p = k;
264 }
265 }
266 }
267
268 static void test_restrict_namespace(void) {
269 char *s = NULL;
270 unsigned long ul;
271 pid_t pid;
272
273 if (!have_namespaces()) {
274 log_notice("Testing without namespaces, skipping %s", __func__);
275 return;
276 }
277
278 log_info("/* %s */", __func__);
279
280 assert_se(namespace_flags_to_string(0, &s) == 0 && isempty(s));
281 s = mfree(s);
282 assert_se(namespace_flags_to_string(CLONE_NEWNS, &s) == 0 && streq(s, "mnt"));
283 s = mfree(s);
284 assert_se(namespace_flags_to_string(CLONE_NEWNS|CLONE_NEWIPC, &s) == 0 && streq(s, "ipc mnt"));
285 s = mfree(s);
286 assert_se(namespace_flags_to_string(CLONE_NEWCGROUP, &s) == 0 && streq(s, "cgroup"));
287 s = mfree(s);
288
289 assert_se(namespace_flags_from_string("mnt", &ul) == 0 && ul == CLONE_NEWNS);
290 assert_se(namespace_flags_from_string(NULL, &ul) == 0 && ul == 0);
291 assert_se(namespace_flags_from_string("", &ul) == 0 && ul == 0);
292 assert_se(namespace_flags_from_string("uts", &ul) == 0 && ul == CLONE_NEWUTS);
293 assert_se(namespace_flags_from_string("mnt uts ipc", &ul) == 0 && ul == (CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC));
294
295 assert_se(namespace_flags_to_string(CLONE_NEWUTS, &s) == 0 && streq(s, "uts"));
296 assert_se(namespace_flags_from_string(s, &ul) == 0 && ul == CLONE_NEWUTS);
297 s = mfree(s);
298 assert_se(namespace_flags_from_string("ipc", &ul) == 0 && ul == CLONE_NEWIPC);
299 assert_se(namespace_flags_to_string(ul, &s) == 0 && streq(s, "ipc"));
300 s = mfree(s);
301
302 assert_se(namespace_flags_to_string(NAMESPACE_FLAGS_ALL, &s) == 0);
303 assert_se(streq(s, "cgroup ipc net mnt pid user uts"));
304 assert_se(namespace_flags_from_string(s, &ul) == 0 && ul == NAMESPACE_FLAGS_ALL);
305 s = mfree(s);
306
307 if (!is_seccomp_available()) {
308 log_notice("Seccomp not available, skipping remaining tests in %s", __func__);
309 return;
310 }
311 if (!have_seccomp_privs()) {
312 log_notice("Not privileged, skipping remaining tests in %s", __func__);
313 return;
314 }
315
316 pid = fork();
317 assert_se(pid >= 0);
318
319 if (pid == 0) {
320
321 assert_se(seccomp_restrict_namespaces(CLONE_NEWNS|CLONE_NEWNET) >= 0);
322
323 assert_se(unshare(CLONE_NEWNS) == 0);
324 assert_se(unshare(CLONE_NEWNET) == 0);
325 assert_se(unshare(CLONE_NEWUTS) == -1);
326 assert_se(errno == EPERM);
327 assert_se(unshare(CLONE_NEWIPC) == -1);
328 assert_se(errno == EPERM);
329 assert_se(unshare(CLONE_NEWNET|CLONE_NEWUTS) == -1);
330 assert_se(errno == EPERM);
331
332 /* We use fd 0 (stdin) here, which of course will fail with EINVAL on setns(). Except of course our
333 * seccomp filter worked, and hits first and makes it return EPERM */
334 assert_se(setns(0, CLONE_NEWNS) == -1);
335 assert_se(errno == EINVAL);
336 assert_se(setns(0, CLONE_NEWNET) == -1);
337 assert_se(errno == EINVAL);
338 assert_se(setns(0, CLONE_NEWUTS) == -1);
339 assert_se(errno == EPERM);
340 assert_se(setns(0, CLONE_NEWIPC) == -1);
341 assert_se(errno == EPERM);
342 assert_se(setns(0, CLONE_NEWNET|CLONE_NEWUTS) == -1);
343 assert_se(errno == EPERM);
344 assert_se(setns(0, 0) == -1);
345 assert_se(errno == EPERM);
346
347 pid = raw_clone(CLONE_NEWNS);
348 assert_se(pid >= 0);
349 if (pid == 0)
350 _exit(EXIT_SUCCESS);
351 pid = raw_clone(CLONE_NEWNET);
352 assert_se(pid >= 0);
353 if (pid == 0)
354 _exit(EXIT_SUCCESS);
355 pid = raw_clone(CLONE_NEWUTS);
356 assert_se(pid < 0);
357 assert_se(errno == EPERM);
358 pid = raw_clone(CLONE_NEWIPC);
359 assert_se(pid < 0);
360 assert_se(errno == EPERM);
361 pid = raw_clone(CLONE_NEWNET|CLONE_NEWUTS);
362 assert_se(pid < 0);
363 assert_se(errno == EPERM);
364
365 _exit(EXIT_SUCCESS);
366 }
367
368 assert_se(wait_for_terminate_and_check("nsseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
369 }
370
371 static void test_protect_sysctl(void) {
372 pid_t pid;
373 _cleanup_free_ char *seccomp = NULL;
374
375 log_info("/* %s */", __func__);
376
377 if (!is_seccomp_available()) {
378 log_notice("Seccomp not available, skipping %s", __func__);
379 return;
380 }
381 if (!have_seccomp_privs()) {
382 log_notice("Not privileged, skipping %s", __func__);
383 return;
384 }
385
386 /* in containers _sysctl() is likely missing anyway */
387 if (detect_container() > 0) {
388 log_notice("Testing in container, skipping %s", __func__);
389 return;
390 }
391
392 assert_se(get_proc_field("/proc/self/status", "Seccomp", WHITESPACE, &seccomp) == 0);
393 if (!streq(seccomp, "0"))
394 log_warning("Warning: seccomp filter detected, results may be unreliable for %s", __func__);
395
396 pid = fork();
397 assert_se(pid >= 0);
398
399 if (pid == 0) {
400 #if defined __NR__sysctl && __NR__sysctl >= 0
401 assert_se(syscall(__NR__sysctl, NULL) < 0);
402 assert_se(IN_SET(errno, EFAULT, ENOSYS));
403 #endif
404
405 assert_se(seccomp_protect_sysctl() >= 0);
406
407 #if HAVE_VALGRIND_VALGRIND_H
408 if (RUNNING_ON_VALGRIND) {
409 log_info("Running on valgrind, skipping syscall/EPERM test");
410 _exit(EXIT_SUCCESS);
411 }
412 #endif
413
414 #if defined __NR__sysctl && __NR__sysctl >= 0
415 assert_se(syscall(__NR__sysctl, 0, 0, 0) < 0);
416 assert_se(errno == EPERM);
417 #endif
418
419 _exit(EXIT_SUCCESS);
420 }
421
422 assert_se(wait_for_terminate_and_check("sysctlseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
423 }
424
425 static void test_protect_syslog(void) {
426 pid_t pid;
427
428 log_info("/* %s */", __func__);
429
430 if (!is_seccomp_available()) {
431 log_notice("Seccomp not available, skipping %s", __func__);
432 return;
433 }
434 if (!have_seccomp_privs()) {
435 log_notice("Not privileged, skipping %s", __func__);
436 return;
437 }
438
439 /* in containers syslog() is likely missing anyway */
440 if (detect_container() > 0) {
441 log_notice("Testing in container, skipping %s", __func__);
442 return;
443 }
444
445 pid = fork();
446 assert_se(pid >= 0);
447
448 if (pid == 0) {
449 #if defined __NR_syslog && __NR_syslog >= 0
450 assert_se(syscall(__NR_syslog, -1, NULL, 0) < 0);
451 assert_se(errno == EINVAL);
452 #endif
453
454 assert_se(seccomp_protect_syslog() >= 0);
455
456 #if defined __NR_syslog && __NR_syslog >= 0
457 assert_se(syscall(__NR_syslog, 0, 0, 0) < 0);
458 assert_se(errno == EPERM);
459 #endif
460
461 _exit(EXIT_SUCCESS);
462 }
463
464 assert_se(wait_for_terminate_and_check("syslogseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
465 }
466
467 static void test_restrict_address_families(void) {
468 pid_t pid;
469
470 log_info("/* %s */", __func__);
471
472 if (!is_seccomp_available()) {
473 log_notice("Seccomp not available, skipping %s", __func__);
474 return;
475 }
476 if (!have_seccomp_privs()) {
477 log_notice("Not privileged, skipping %s", __func__);
478 return;
479 }
480
481 pid = fork();
482 assert_se(pid >= 0);
483
484 if (pid == 0) {
485 int fd;
486 Set *s;
487
488 fd = socket(AF_INET, SOCK_DGRAM, 0);
489 assert_se(fd >= 0);
490 safe_close(fd);
491
492 fd = socket(AF_UNIX, SOCK_DGRAM, 0);
493 assert_se(fd >= 0);
494 safe_close(fd);
495
496 fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
497 assert_se(fd >= 0);
498 safe_close(fd);
499
500 assert_se(s = set_new(NULL));
501 assert_se(set_put(s, INT_TO_PTR(AF_UNIX)) >= 0);
502
503 assert_se(seccomp_restrict_address_families(s, false) >= 0);
504
505 fd = socket(AF_INET, SOCK_DGRAM, 0);
506 assert_se(fd >= 0);
507 safe_close(fd);
508
509 fd = socket(AF_UNIX, SOCK_DGRAM, 0);
510 #if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
511 assert_se(fd >= 0);
512 safe_close(fd);
513 #else
514 assert_se(fd < 0);
515 assert_se(errno == EAFNOSUPPORT);
516 #endif
517
518 fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
519 assert_se(fd >= 0);
520 safe_close(fd);
521
522 set_clear(s);
523
524 assert_se(set_put(s, INT_TO_PTR(AF_INET)) >= 0);
525
526 assert_se(seccomp_restrict_address_families(s, true) >= 0);
527
528 fd = socket(AF_INET, SOCK_DGRAM, 0);
529 assert_se(fd >= 0);
530 safe_close(fd);
531
532 fd = socket(AF_UNIX, SOCK_DGRAM, 0);
533 #if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
534 assert_se(fd >= 0);
535 safe_close(fd);
536 #else
537 assert_se(fd < 0);
538 assert_se(errno == EAFNOSUPPORT);
539 #endif
540
541 fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
542 #if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
543 assert_se(fd >= 0);
544 safe_close(fd);
545 #else
546 assert_se(fd < 0);
547 assert_se(errno == EAFNOSUPPORT);
548 #endif
549
550 _exit(EXIT_SUCCESS);
551 }
552
553 assert_se(wait_for_terminate_and_check("socketseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
554 }
555
556 static void test_restrict_realtime(void) {
557 pid_t pid;
558
559 log_info("/* %s */", __func__);
560
561 if (!is_seccomp_available()) {
562 log_notice("Seccomp not available, skipping %s", __func__);
563 return;
564 }
565 if (!have_seccomp_privs()) {
566 log_notice("Not privileged, skipping %s", __func__);
567 return;
568 }
569
570 /* in containers RT privs are likely missing anyway */
571 if (detect_container() > 0) {
572 log_notice("Testing in container, skipping %s", __func__);
573 return;
574 }
575
576 pid = fork();
577 assert_se(pid >= 0);
578
579 if (pid == 0) {
580 assert_se(sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) >= 0);
581 assert_se(sched_setscheduler(0, SCHED_RR, &(struct sched_param) { .sched_priority = 1 }) >= 0);
582 assert_se(sched_setscheduler(0, SCHED_IDLE, &(struct sched_param) { .sched_priority = 0 }) >= 0);
583 assert_se(sched_setscheduler(0, SCHED_BATCH, &(struct sched_param) { .sched_priority = 0 }) >= 0);
584 assert_se(sched_setscheduler(0, SCHED_OTHER, &(struct sched_param) {}) >= 0);
585
586 assert_se(seccomp_restrict_realtime() >= 0);
587
588 assert_se(sched_setscheduler(0, SCHED_IDLE, &(struct sched_param) { .sched_priority = 0 }) >= 0);
589 assert_se(sched_setscheduler(0, SCHED_BATCH, &(struct sched_param) { .sched_priority = 0 }) >= 0);
590 assert_se(sched_setscheduler(0, SCHED_OTHER, &(struct sched_param) {}) >= 0);
591
592 assert_se(sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) < 0);
593 assert_se(errno == EPERM);
594 assert_se(sched_setscheduler(0, SCHED_RR, &(struct sched_param) { .sched_priority = 1 }) < 0);
595 assert_se(errno == EPERM);
596
597 _exit(EXIT_SUCCESS);
598 }
599
600 assert_se(wait_for_terminate_and_check("realtimeseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
601 }
602
603 static void test_memory_deny_write_execute_mmap(void) {
604 pid_t pid;
605
606 log_info("/* %s */", __func__);
607
608 if (!is_seccomp_available()) {
609 log_notice("Seccomp not available, skipping %s", __func__);
610 return;
611 }
612 if (!have_seccomp_privs()) {
613 log_notice("Not privileged, skipping %s", __func__);
614 return;
615 }
616 #if HAVE_VALGRIND_VALGRIND_H
617 if (RUNNING_ON_VALGRIND) {
618 log_notice("Running on valgrind, skipping %s", __func__);
619 return;
620 }
621 #endif
622 #if HAS_FEATURE_ADDRESS_SANITIZER
623 log_notice("Running on address sanitizer, skipping %s", __func__);
624 return;
625 #endif
626
627 pid = fork();
628 assert_se(pid >= 0);
629
630 if (pid == 0) {
631 void *p;
632
633 p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
634 assert_se(p != MAP_FAILED);
635 assert_se(munmap(p, page_size()) >= 0);
636
637 p = mmap(NULL, page_size(), PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
638 assert_se(p != MAP_FAILED);
639 assert_se(munmap(p, page_size()) >= 0);
640
641 assert_se(seccomp_memory_deny_write_execute() >= 0);
642
643 p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
644 #if defined(__x86_64__) || defined(__i386__) || defined(__powerpc64__) || defined(__arm__) || defined(__aarch64__)
645 assert_se(p == MAP_FAILED);
646 assert_se(errno == EPERM);
647 #endif
648 /* Depending on kernel, libseccomp, and glibc versions, other architectures
649 * might fail or not. Let's not assert success. */
650 if (p != MAP_FAILED)
651 assert_se(munmap(p, page_size()) == 0);
652
653 p = mmap(NULL, page_size(), PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
654 assert_se(p != MAP_FAILED);
655 assert_se(munmap(p, page_size()) >= 0);
656
657 _exit(EXIT_SUCCESS);
658 }
659
660 assert_se(wait_for_terminate_and_check("memoryseccomp-mmap", pid, WAIT_LOG) == EXIT_SUCCESS);
661 }
662
663 static void test_memory_deny_write_execute_shmat(void) {
664 int shmid;
665 pid_t pid;
666 uint32_t arch;
667
668 log_info("/* %s */", __func__);
669
670 SECCOMP_FOREACH_LOCAL_ARCH(arch) {
671 log_debug("arch %s: SCMP_SYS(mmap) = %d", seccomp_arch_to_string(arch), SCMP_SYS(mmap));
672 log_debug("arch %s: SCMP_SYS(mmap2) = %d", seccomp_arch_to_string(arch), SCMP_SYS(mmap2));
673 log_debug("arch %s: SCMP_SYS(shmget) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmget));
674 log_debug("arch %s: SCMP_SYS(shmat) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmat));
675 log_debug("arch %s: SCMP_SYS(shmdt) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmdt));
676 }
677
678 if (!is_seccomp_available()) {
679 log_notice("Seccomp not available, skipping %s", __func__);
680 return;
681 }
682 if (!have_seccomp_privs()) {
683 log_notice("Not privileged, skipping %s", __func__);
684 return;
685 }
686 #if HAVE_VALGRIND_VALGRIND_H
687 if (RUNNING_ON_VALGRIND) {
688 log_notice("Running on valgrind, skipping %s", __func__);
689 return;
690 }
691 #endif
692 #if HAS_FEATURE_ADDRESS_SANITIZER
693 log_notice("Running on address sanitizer, skipping %s", __func__);
694 return;
695 #endif
696
697 shmid = shmget(IPC_PRIVATE, page_size(), 0);
698 assert_se(shmid >= 0);
699
700 pid = fork();
701 assert_se(pid >= 0);
702
703 if (pid == 0) {
704 void *p;
705
706 p = shmat(shmid, NULL, 0);
707 assert_se(p != MAP_FAILED);
708 assert_se(shmdt(p) == 0);
709
710 p = shmat(shmid, NULL, SHM_EXEC);
711 assert_se(p != MAP_FAILED);
712 assert_se(shmdt(p) == 0);
713
714 assert_se(seccomp_memory_deny_write_execute() >= 0);
715
716 p = shmat(shmid, NULL, SHM_EXEC);
717 log_debug_errno(p == MAP_FAILED ? errno : 0, "shmat(SHM_EXEC): %m");
718 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
719 assert_se(p == MAP_FAILED);
720 assert_se(errno == EPERM);
721 #endif
722 /* Depending on kernel, libseccomp, and glibc versions, other architectures
723 * might fail or not. Let's not assert success. */
724 if (p != MAP_FAILED)
725 assert_se(shmdt(p) == 0);
726
727 p = shmat(shmid, NULL, 0);
728 log_debug_errno(p == MAP_FAILED ? errno : 0, "shmat(0): %m");
729 assert_se(p != MAP_FAILED);
730 assert_se(shmdt(p) == 0);
731
732 _exit(EXIT_SUCCESS);
733 }
734
735 assert_se(wait_for_terminate_and_check("memoryseccomp-shmat", pid, WAIT_LOG) == EXIT_SUCCESS);
736 }
737
738 static void test_restrict_archs(void) {
739 pid_t pid;
740
741 log_info("/* %s */", __func__);
742
743 if (!is_seccomp_available()) {
744 log_notice("Seccomp not available, skipping %s", __func__);
745 return;
746 }
747 if (!have_seccomp_privs()) {
748 log_notice("Not privileged, skipping %s", __func__);
749 return;
750 }
751
752 pid = fork();
753 assert_se(pid >= 0);
754
755 if (pid == 0) {
756 _cleanup_set_free_ Set *s = NULL;
757
758 assert_se(access("/", F_OK) >= 0);
759
760 assert_se(s = set_new(NULL));
761
762 #ifdef __x86_64__
763 assert_se(set_put(s, UINT32_TO_PTR(SCMP_ARCH_X86+1)) >= 0);
764 #endif
765 assert_se(seccomp_restrict_archs(s) >= 0);
766
767 assert_se(access("/", F_OK) >= 0);
768 assert_se(seccomp_restrict_archs(NULL) >= 0);
769
770 assert_se(access("/", F_OK) >= 0);
771
772 _exit(EXIT_SUCCESS);
773 }
774
775 assert_se(wait_for_terminate_and_check("archseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
776 }
777
778 static void test_load_syscall_filter_set_raw(void) {
779 pid_t pid;
780
781 log_info("/* %s */", __func__);
782
783 if (!is_seccomp_available()) {
784 log_notice("Seccomp not available, skipping %s", __func__);
785 return;
786 }
787 if (!have_seccomp_privs()) {
788 log_notice("Not privileged, skipping %s", __func__);
789 return;
790 }
791
792 pid = fork();
793 assert_se(pid >= 0);
794
795 if (pid == 0) {
796 _cleanup_hashmap_free_ Hashmap *s = NULL;
797
798 assert_se(access("/", F_OK) >= 0);
799 assert_se(poll(NULL, 0, 0) == 0);
800
801 assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, scmp_act_kill_process(), true) >= 0);
802 assert_se(access("/", F_OK) >= 0);
803 assert_se(poll(NULL, 0, 0) == 0);
804
805 assert_se(s = hashmap_new(NULL));
806 #if defined __NR_access && __NR_access >= 0
807 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_access + 1), INT_TO_PTR(-1)) >= 0);
808 log_debug("has access()");
809 #endif
810 #if defined __NR_faccessat && __NR_faccessat >= 0
811 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(-1)) >= 0);
812 log_debug("has faccessat()");
813 #endif
814 #if defined __NR_faccessat2 && __NR_faccessat2 >= 0
815 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat2 + 1), INT_TO_PTR(-1)) >= 0);
816 log_debug("has faccessat2()");
817 #endif
818
819 assert_se(!hashmap_isempty(s));
820 assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
821
822 assert_se(access("/", F_OK) < 0);
823 assert_se(errno == EUCLEAN);
824
825 assert_se(poll(NULL, 0, 0) == 0);
826
827 hashmap_clear(s);
828 #if defined __NR_access && __NR_access >= 0
829 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_access + 1), INT_TO_PTR(EILSEQ)) >= 0);
830 #endif
831 #if defined __NR_faccessat && __NR_faccessat >= 0
832 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(EILSEQ)) >= 0);
833 #endif
834 #if defined __NR_faccessat2 && __NR_faccessat2 >= 0
835 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat2 + 1), INT_TO_PTR(EILSEQ)) >= 0);
836 #endif
837
838 assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
839
840 assert_se(access("/", F_OK) < 0);
841 assert_se(errno == EILSEQ);
842
843 assert_se(poll(NULL, 0, 0) == 0);
844
845 hashmap_clear(s);
846 #if defined __NR_poll && __NR_poll >= 0
847 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_poll + 1), INT_TO_PTR(-1)) >= 0);
848 log_debug("has poll()");
849 #endif
850 #if defined __NR_ppoll && __NR_ppoll >= 0
851 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(-1)) >= 0);
852 log_debug("has ppoll()");
853 #endif
854 #if defined __NR_ppoll_time64 && __NR_ppoll_time64 >= 0
855 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll_time64 + 1), INT_TO_PTR(-1)) >= 0);
856 log_debug("has ppoll_time64()");
857 #endif
858
859 assert_se(!hashmap_isempty(s));
860 assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
861
862 assert_se(access("/", F_OK) < 0);
863 assert_se(errno == EILSEQ);
864
865 assert_se(poll(NULL, 0, 0) < 0);
866 assert_se(errno == EUNATCH);
867
868 hashmap_clear(s);
869 #if defined __NR_poll && __NR_poll >= 0
870 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_poll + 1), INT_TO_PTR(EILSEQ)) >= 0);
871 #endif
872 #if defined __NR_ppoll && __NR_ppoll >= 0
873 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(EILSEQ)) >= 0);
874 #endif
875 #if defined __NR_ppoll_time64 && __NR_ppoll_time64 >= 0
876 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll_time64 + 1), INT_TO_PTR(EILSEQ)) >= 0);
877 #endif
878
879 assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
880
881 assert_se(access("/", F_OK) < 0);
882 assert_se(errno == EILSEQ);
883
884 assert_se(poll(NULL, 0, 0) < 0);
885 assert_se(errno == EILSEQ);
886
887 _exit(EXIT_SUCCESS);
888 }
889
890 assert_se(wait_for_terminate_and_check("syscallrawseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
891 }
892
893 static void test_lock_personality(void) {
894 unsigned long current;
895 pid_t pid;
896
897 log_info("/* %s */", __func__);
898
899 if (!is_seccomp_available()) {
900 log_notice("Seccomp not available, skipping %s", __func__);
901 return;
902 }
903 if (!have_seccomp_privs()) {
904 log_notice("Not privileged, skipping %s", __func__);
905 return;
906 }
907
908 assert_se(opinionated_personality(&current) >= 0);
909
910 log_info("current personality=%lu", current);
911
912 pid = fork();
913 assert_se(pid >= 0);
914
915 if (pid == 0) {
916 assert_se(seccomp_lock_personality(current) >= 0);
917
918 assert_se((unsigned long) safe_personality(current) == current);
919
920 /* Note, we also test that safe_personality() works correctly, by checkig whether errno is properly
921 * set, in addition to the return value */
922 errno = 0;
923 assert_se(safe_personality(PER_LINUX | ADDR_NO_RANDOMIZE) == -EPERM);
924 assert_se(errno == EPERM);
925
926 assert_se(safe_personality(PER_LINUX | MMAP_PAGE_ZERO) == -EPERM);
927 assert_se(safe_personality(PER_LINUX | ADDR_COMPAT_LAYOUT) == -EPERM);
928 assert_se(safe_personality(PER_LINUX | READ_IMPLIES_EXEC) == -EPERM);
929 assert_se(safe_personality(PER_LINUX_32BIT) == -EPERM);
930 assert_se(safe_personality(PER_SVR4) == -EPERM);
931 assert_se(safe_personality(PER_BSD) == -EPERM);
932 assert_se(safe_personality(current == PER_LINUX ? PER_LINUX32 : PER_LINUX) == -EPERM);
933 assert_se(safe_personality(PER_LINUX32_3GB) == -EPERM);
934 assert_se(safe_personality(PER_UW7) == -EPERM);
935 assert_se(safe_personality(0x42) == -EPERM);
936
937 assert_se(safe_personality(PERSONALITY_INVALID) == -EPERM); /* maybe remove this later */
938
939 assert_se((unsigned long) personality(current) == current);
940 _exit(EXIT_SUCCESS);
941 }
942
943 assert_se(wait_for_terminate_and_check("lockpersonalityseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
944 }
945
946 static int real_open(const char *path, int flags, mode_t mode) {
947 /* glibc internally calls openat() when open() is requested. Let's hence define our own wrapper for
948 * testing purposes that calls the real syscall, on architectures where SYS_open is defined. On
949 * other architectures, let's just fall back to the glibc call. */
950
951 #if defined __NR_open && __NR_open >= 0
952 return (int) syscall(__NR_open, path, flags, mode);
953 #else
954 return open(path, flags, mode);
955 #endif
956 }
957
958 static void test_restrict_suid_sgid(void) {
959 pid_t pid;
960
961 log_info("/* %s */", __func__);
962
963 if (!is_seccomp_available()) {
964 log_notice("Seccomp not available, skipping %s", __func__);
965 return;
966 }
967 if (!have_seccomp_privs()) {
968 log_notice("Not privileged, skipping %s", __func__);
969 return;
970 }
971
972 pid = fork();
973 assert_se(pid >= 0);
974
975 if (pid == 0) {
976 char path[] = "/tmp/suidsgidXXXXXX", dir[] = "/tmp/suidsgiddirXXXXXX";
977 int fd = -1, k = -1;
978 const char *z;
979
980 fd = mkostemp_safe(path);
981 assert_se(fd >= 0);
982
983 assert_se(mkdtemp(dir));
984 z = strjoina(dir, "/test");
985
986 assert_se(chmod(path, 0755 | S_ISUID) >= 0);
987 assert_se(chmod(path, 0755 | S_ISGID) >= 0);
988 assert_se(chmod(path, 0755 | S_ISGID | S_ISUID) >= 0);
989 assert_se(chmod(path, 0755) >= 0);
990
991 assert_se(fchmod(fd, 0755 | S_ISUID) >= 0);
992 assert_se(fchmod(fd, 0755 | S_ISGID) >= 0);
993 assert_se(fchmod(fd, 0755 | S_ISGID | S_ISUID) >= 0);
994 assert_se(fchmod(fd, 0755) >= 0);
995
996 assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) >= 0);
997 assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) >= 0);
998 assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0);
999 assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0);
1000
1001 k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID);
1002 k = safe_close(k);
1003 assert_se(unlink(z) >= 0);
1004
1005 k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID);
1006 k = safe_close(k);
1007 assert_se(unlink(z) >= 0);
1008
1009 k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID);
1010 k = safe_close(k);
1011 assert_se(unlink(z) >= 0);
1012
1013 k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
1014 k = safe_close(k);
1015 assert_se(unlink(z) >= 0);
1016
1017 k = creat(z, 0644 | S_ISUID);
1018 k = safe_close(k);
1019 assert_se(unlink(z) >= 0);
1020
1021 k = creat(z, 0644 | S_ISGID);
1022 k = safe_close(k);
1023 assert_se(unlink(z) >= 0);
1024
1025 k = creat(z, 0644 | S_ISUID | S_ISGID);
1026 k = safe_close(k);
1027 assert_se(unlink(z) >= 0);
1028
1029 k = creat(z, 0644);
1030 k = safe_close(k);
1031 assert_se(unlink(z) >= 0);
1032
1033 k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID);
1034 k = safe_close(k);
1035 assert_se(unlink(z) >= 0);
1036
1037 k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID);
1038 k = safe_close(k);
1039 assert_se(unlink(z) >= 0);
1040
1041 k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID);
1042 k = safe_close(k);
1043 assert_se(unlink(z) >= 0);
1044
1045 k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
1046 k = safe_close(k);
1047 assert_se(unlink(z) >= 0);
1048
1049 assert_se(mkdir(z, 0755 | S_ISUID) >= 0);
1050 assert_se(rmdir(z) >= 0);
1051 assert_se(mkdir(z, 0755 | S_ISGID) >= 0);
1052 assert_se(rmdir(z) >= 0);
1053 assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) >= 0);
1054 assert_se(rmdir(z) >= 0);
1055 assert_se(mkdir(z, 0755) >= 0);
1056 assert_se(rmdir(z) >= 0);
1057
1058 assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) >= 0);
1059 assert_se(rmdir(z) >= 0);
1060 assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) >= 0);
1061 assert_se(rmdir(z) >= 0);
1062 assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) >= 0);
1063 assert_se(rmdir(z) >= 0);
1064 assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0);
1065 assert_se(rmdir(z) >= 0);
1066
1067 assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) >= 0);
1068 assert_se(unlink(z) >= 0);
1069 assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) >= 0);
1070 assert_se(unlink(z) >= 0);
1071 assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0);
1072 assert_se(unlink(z) >= 0);
1073 assert_se(mknod(z, S_IFREG | 0755, 0) >= 0);
1074 assert_se(unlink(z) >= 0);
1075
1076 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) >= 0);
1077 assert_se(unlink(z) >= 0);
1078 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) >= 0);
1079 assert_se(unlink(z) >= 0);
1080 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0);
1081 assert_se(unlink(z) >= 0);
1082 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0);
1083 assert_se(unlink(z) >= 0);
1084
1085 assert_se(seccomp_restrict_suid_sgid() >= 0);
1086
1087 assert_se(chmod(path, 0775 | S_ISUID) < 0 && errno == EPERM);
1088 assert_se(chmod(path, 0775 | S_ISGID) < 0 && errno == EPERM);
1089 assert_se(chmod(path, 0775 | S_ISGID | S_ISUID) < 0 && errno == EPERM);
1090 assert_se(chmod(path, 0775) >= 0);
1091
1092 assert_se(fchmod(fd, 0775 | S_ISUID) < 0 && errno == EPERM);
1093 assert_se(fchmod(fd, 0775 | S_ISGID) < 0 && errno == EPERM);
1094 assert_se(fchmod(fd, 0775 | S_ISGID | S_ISUID) < 0 && errno == EPERM);
1095 assert_se(fchmod(fd, 0775) >= 0);
1096
1097 assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) < 0 && errno == EPERM);
1098 assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) < 0 && errno == EPERM);
1099 assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM);
1100 assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0);
1101
1102 assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM);
1103 assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM);
1104 assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
1105 k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
1106 k = safe_close(k);
1107 assert_se(unlink(z) >= 0);
1108
1109 assert_se(creat(z, 0644 | S_ISUID) < 0 && errno == EPERM);
1110 assert_se(creat(z, 0644 | S_ISGID) < 0 && errno == EPERM);
1111 assert_se(creat(z, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
1112 k = creat(z, 0644);
1113 k = safe_close(k);
1114 assert_se(unlink(z) >= 0);
1115
1116 assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM);
1117 assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM);
1118 assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
1119 k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
1120 k = safe_close(k);
1121 assert_se(unlink(z) >= 0);
1122
1123 assert_se(mkdir(z, 0755 | S_ISUID) < 0 && errno == EPERM);
1124 assert_se(mkdir(z, 0755 | S_ISGID) < 0 && errno == EPERM);
1125 assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
1126 assert_se(mkdir(z, 0755) >= 0);
1127 assert_se(rmdir(z) >= 0);
1128
1129 assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) < 0 && errno == EPERM);
1130 assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) < 0 && errno == EPERM);
1131 assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
1132 assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0);
1133 assert_se(rmdir(z) >= 0);
1134
1135 assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM);
1136 assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM);
1137 assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM);
1138 assert_se(mknod(z, S_IFREG | 0755, 0) >= 0);
1139 assert_se(unlink(z) >= 0);
1140
1141 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM);
1142 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM);
1143 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM);
1144 assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0);
1145 assert_se(unlink(z) >= 0);
1146
1147 assert_se(unlink(path) >= 0);
1148 assert_se(rm_rf(dir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
1149
1150 _exit(EXIT_SUCCESS);
1151 }
1152
1153 assert_se(wait_for_terminate_and_check("suidsgidseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
1154 }
1155
1156 int main(int argc, char *argv[]) {
1157 test_setup_logging(LOG_DEBUG);
1158
1159 test_parse_syscall_and_errno();
1160 test_seccomp_arch_to_string();
1161 test_architecture_table();
1162 test_syscall_filter_set_find();
1163 test_filter_sets();
1164 test_filter_sets_ordered();
1165 test_restrict_namespace();
1166 test_protect_sysctl();
1167 test_protect_syslog();
1168 test_restrict_address_families();
1169 test_restrict_realtime();
1170 test_memory_deny_write_execute_mmap();
1171 test_memory_deny_write_execute_shmat();
1172 test_restrict_archs();
1173 test_load_syscall_filter_set_raw();
1174 test_lock_personality();
1175 test_restrict_suid_sgid();
1176
1177 return 0;
1178 }