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