]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - tools/testing/selftests/seccomp/seccomp_bpf.c
selftests/seccomp: Make seccomp tests work on big endian
[mirror_ubuntu-focal-kernel.git] / tools / testing / selftests / seccomp / seccomp_bpf.c
CommitLineData
c99ee51a
KC
1/*
2 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by the GPLv2 license.
4 *
5 * Test code for seccomp bpf.
6 */
7
8#include <asm/siginfo.h>
9#define __have_siginfo_t 1
10#define __have_sigval_t 1
11#define __have_sigevent_t 1
12
13#include <errno.h>
14#include <linux/filter.h>
15#include <sys/prctl.h>
16#include <sys/ptrace.h>
17#include <sys/user.h>
18#include <linux/prctl.h>
19#include <linux/ptrace.h>
20#include <linux/seccomp.h>
21#include <poll.h>
22#include <pthread.h>
23#include <semaphore.h>
24#include <signal.h>
25#include <stddef.h>
26#include <stdbool.h>
27#include <string.h>
28#include <linux/elf.h>
29#include <sys/uio.h>
30
31#define _GNU_SOURCE
32#include <unistd.h>
33#include <sys/syscall.h>
34
35#include "test_harness.h"
36
37#ifndef PR_SET_PTRACER
38# define PR_SET_PTRACER 0x59616d61
39#endif
40
41#ifndef PR_SET_NO_NEW_PRIVS
42#define PR_SET_NO_NEW_PRIVS 38
43#define PR_GET_NO_NEW_PRIVS 39
44#endif
45
46#ifndef PR_SECCOMP_EXT
47#define PR_SECCOMP_EXT 43
48#endif
49
50#ifndef SECCOMP_EXT_ACT
51#define SECCOMP_EXT_ACT 1
52#endif
53
54#ifndef SECCOMP_EXT_ACT_TSYNC
55#define SECCOMP_EXT_ACT_TSYNC 1
56#endif
57
58#ifndef SECCOMP_MODE_STRICT
59#define SECCOMP_MODE_STRICT 1
60#endif
61
62#ifndef SECCOMP_MODE_FILTER
63#define SECCOMP_MODE_FILTER 2
64#endif
65
66#ifndef SECCOMP_RET_KILL
67#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
68#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
69#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
70#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
71#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
72
73/* Masks for the return value sections. */
74#define SECCOMP_RET_ACTION 0x7fff0000U
75#define SECCOMP_RET_DATA 0x0000ffffU
76
77struct seccomp_data {
78 int nr;
79 __u32 arch;
80 __u64 instruction_pointer;
81 __u64 args[6];
82};
83#endif
84
c385d0db 85#if __BYTE_ORDER == __LITTLE_ENDIAN
c99ee51a 86#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
c385d0db
ME
87#elif __BYTE_ORDER == __BIG_ENDIAN
88#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]) + sizeof(__u32))
89#else
90#error "wut? Unknown __BYTE_ORDER?!"
91#endif
c99ee51a
KC
92
93#define SIBLING_EXIT_UNKILLED 0xbadbeef
94#define SIBLING_EXIT_FAILURE 0xbadface
95#define SIBLING_EXIT_NEWPRIVS 0xbadfeed
96
97TEST(mode_strict_support)
98{
99 long ret;
100
101 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);
102 ASSERT_EQ(0, ret) {
103 TH_LOG("Kernel does not support CONFIG_SECCOMP");
104 }
105 syscall(__NR_exit, 1);
106}
107
108TEST_SIGNAL(mode_strict_cannot_call_prctl, SIGKILL)
109{
110 long ret;
111
112 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);
113 ASSERT_EQ(0, ret) {
114 TH_LOG("Kernel does not support CONFIG_SECCOMP");
115 }
116 syscall(__NR_prctl, PR_SET_SECCOMP, SECCOMP_MODE_FILTER,
117 NULL, NULL, NULL);
118 EXPECT_FALSE(true) {
119 TH_LOG("Unreachable!");
120 }
121}
122
123/* Note! This doesn't test no new privs behavior */
124TEST(no_new_privs_support)
125{
126 long ret;
127
128 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
129 EXPECT_EQ(0, ret) {
130 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
131 }
132}
133
134/* Tests kernel support by checking for a copy_from_user() fault on * NULL. */
135TEST(mode_filter_support)
136{
137 long ret;
138
139 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
140 ASSERT_EQ(0, ret) {
141 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
142 }
143 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, NULL, NULL);
144 EXPECT_EQ(-1, ret);
145 EXPECT_EQ(EFAULT, errno) {
146 TH_LOG("Kernel does not support CONFIG_SECCOMP_FILTER!");
147 }
148}
149
150TEST(mode_filter_without_nnp)
151{
152 struct sock_filter filter[] = {
153 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
154 };
155 struct sock_fprog prog = {
156 .len = (unsigned short)ARRAY_SIZE(filter),
157 .filter = filter,
158 };
159 long ret;
160
161 ret = prctl(PR_GET_NO_NEW_PRIVS, 0, NULL, 0, 0);
162 ASSERT_LE(0, ret) {
163 TH_LOG("Expected 0 or unsupported for NO_NEW_PRIVS");
164 }
165 errno = 0;
166 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
167 /* Succeeds with CAP_SYS_ADMIN, fails without */
168 /* TODO(wad) check caps not euid */
169 if (geteuid()) {
170 EXPECT_EQ(-1, ret);
171 EXPECT_EQ(EACCES, errno);
172 } else {
173 EXPECT_EQ(0, ret);
174 }
175}
176
177#define MAX_INSNS_PER_PATH 32768
178
179TEST(filter_size_limits)
180{
181 int i;
182 int count = BPF_MAXINSNS + 1;
183 struct sock_filter allow[] = {
184 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
185 };
186 struct sock_filter *filter;
187 struct sock_fprog prog = { };
188 long ret;
189
190 filter = calloc(count, sizeof(*filter));
191 ASSERT_NE(NULL, filter);
192
193 for (i = 0; i < count; i++)
194 filter[i] = allow[0];
195
196 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
197 ASSERT_EQ(0, ret);
198
199 prog.filter = filter;
200 prog.len = count;
201
202 /* Too many filter instructions in a single filter. */
203 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
204 ASSERT_NE(0, ret) {
205 TH_LOG("Installing %d insn filter was allowed", prog.len);
206 }
207
208 /* One less is okay, though. */
209 prog.len -= 1;
210 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
211 ASSERT_EQ(0, ret) {
212 TH_LOG("Installing %d insn filter wasn't allowed", prog.len);
213 }
214}
215
216TEST(filter_chain_limits)
217{
218 int i;
219 int count = BPF_MAXINSNS;
220 struct sock_filter allow[] = {
221 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
222 };
223 struct sock_filter *filter;
224 struct sock_fprog prog = { };
225 long ret;
226
227 filter = calloc(count, sizeof(*filter));
228 ASSERT_NE(NULL, filter);
229
230 for (i = 0; i < count; i++)
231 filter[i] = allow[0];
232
233 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
234 ASSERT_EQ(0, ret);
235
236 prog.filter = filter;
237 prog.len = 1;
238
239 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
240 ASSERT_EQ(0, ret);
241
242 prog.len = count;
243
244 /* Too many total filter instructions. */
245 for (i = 0; i < MAX_INSNS_PER_PATH; i++) {
246 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
247 if (ret != 0)
248 break;
249 }
250 ASSERT_NE(0, ret) {
251 TH_LOG("Allowed %d %d-insn filters (total with penalties:%d)",
252 i, count, i * (count + 4));
253 }
254}
255
256TEST(mode_filter_cannot_move_to_strict)
257{
258 struct sock_filter filter[] = {
259 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
260 };
261 struct sock_fprog prog = {
262 .len = (unsigned short)ARRAY_SIZE(filter),
263 .filter = filter,
264 };
265 long ret;
266
267 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
268 ASSERT_EQ(0, ret);
269
270 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
271 ASSERT_EQ(0, ret);
272
273 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, 0, 0);
274 EXPECT_EQ(-1, ret);
275 EXPECT_EQ(EINVAL, errno);
276}
277
278
279TEST(mode_filter_get_seccomp)
280{
281 struct sock_filter filter[] = {
282 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
283 };
284 struct sock_fprog prog = {
285 .len = (unsigned short)ARRAY_SIZE(filter),
286 .filter = filter,
287 };
288 long ret;
289
290 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
291 ASSERT_EQ(0, ret);
292
293 ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
294 EXPECT_EQ(0, ret);
295
296 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
297 ASSERT_EQ(0, ret);
298
299 ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
300 EXPECT_EQ(2, ret);
301}
302
303
304TEST(ALLOW_all)
305{
306 struct sock_filter filter[] = {
307 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
308 };
309 struct sock_fprog prog = {
310 .len = (unsigned short)ARRAY_SIZE(filter),
311 .filter = filter,
312 };
313 long ret;
314
315 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
316 ASSERT_EQ(0, ret);
317
318 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
319 ASSERT_EQ(0, ret);
320}
321
322TEST(empty_prog)
323{
324 struct sock_filter filter[] = {
325 };
326 struct sock_fprog prog = {
327 .len = (unsigned short)ARRAY_SIZE(filter),
328 .filter = filter,
329 };
330 long ret;
331
332 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
333 ASSERT_EQ(0, ret);
334
335 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
336 EXPECT_EQ(-1, ret);
337 EXPECT_EQ(EINVAL, errno);
338}
339
340TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS)
341{
342 struct sock_filter filter[] = {
343 BPF_STMT(BPF_RET|BPF_K, 0x10000000U),
344 };
345 struct sock_fprog prog = {
346 .len = (unsigned short)ARRAY_SIZE(filter),
347 .filter = filter,
348 };
349 long ret;
350
351 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
352 ASSERT_EQ(0, ret);
353
354 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
355 ASSERT_EQ(0, ret);
356 EXPECT_EQ(0, syscall(__NR_getpid)) {
357 TH_LOG("getpid() shouldn't ever return");
358 }
359}
360
361/* return code >= 0x80000000 is unused. */
362TEST_SIGNAL(unknown_ret_is_kill_above_allow, SIGSYS)
363{
364 struct sock_filter filter[] = {
365 BPF_STMT(BPF_RET|BPF_K, 0x90000000U),
366 };
367 struct sock_fprog prog = {
368 .len = (unsigned short)ARRAY_SIZE(filter),
369 .filter = filter,
370 };
371 long ret;
372
373 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
374 ASSERT_EQ(0, ret);
375
376 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
377 ASSERT_EQ(0, ret);
378 EXPECT_EQ(0, syscall(__NR_getpid)) {
379 TH_LOG("getpid() shouldn't ever return");
380 }
381}
382
383TEST_SIGNAL(KILL_all, SIGSYS)
384{
385 struct sock_filter filter[] = {
386 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
387 };
388 struct sock_fprog prog = {
389 .len = (unsigned short)ARRAY_SIZE(filter),
390 .filter = filter,
391 };
392 long ret;
393
394 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
395 ASSERT_EQ(0, ret);
396
397 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
398 ASSERT_EQ(0, ret);
399}
400
401TEST_SIGNAL(KILL_one, SIGSYS)
402{
403 struct sock_filter filter[] = {
404 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
405 offsetof(struct seccomp_data, nr)),
406 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),
407 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
408 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
409 };
410 struct sock_fprog prog = {
411 .len = (unsigned short)ARRAY_SIZE(filter),
412 .filter = filter,
413 };
414 long ret;
415 pid_t parent = getppid();
416
417 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
418 ASSERT_EQ(0, ret);
419
420 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
421 ASSERT_EQ(0, ret);
422
423 EXPECT_EQ(parent, syscall(__NR_getppid));
424 /* getpid() should never return. */
425 EXPECT_EQ(0, syscall(__NR_getpid));
426}
427
428TEST_SIGNAL(KILL_one_arg_one, SIGSYS)
429{
430 struct sock_filter filter[] = {
431 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
432 offsetof(struct seccomp_data, nr)),
433 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
434 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
435 /* Only both with lower 32-bit for now. */
436 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
437 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
438 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
439 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
440 };
441 struct sock_fprog prog = {
442 .len = (unsigned short)ARRAY_SIZE(filter),
443 .filter = filter,
444 };
445 long ret;
446 pid_t parent = getppid();
447 pid_t pid = getpid();
448
449 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
450 ASSERT_EQ(0, ret);
451
452 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
453 ASSERT_EQ(0, ret);
454
455 EXPECT_EQ(parent, syscall(__NR_getppid));
456 EXPECT_EQ(pid, syscall(__NR_getpid));
457 /* getpid() should never return. */
458 EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE));
459}
460
461TEST_SIGNAL(KILL_one_arg_six, SIGSYS)
462{
463 struct sock_filter filter[] = {
464 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
465 offsetof(struct seccomp_data, nr)),
466 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
467 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
468 /* Only both with lower 32-bit for now. */
469 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
470 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
471 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
472 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
473 };
474 struct sock_fprog prog = {
475 .len = (unsigned short)ARRAY_SIZE(filter),
476 .filter = filter,
477 };
478 long ret;
479 pid_t parent = getppid();
480 pid_t pid = getpid();
481
482 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
483 ASSERT_EQ(0, ret);
484
485 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
486 ASSERT_EQ(0, ret);
487
488 EXPECT_EQ(parent, syscall(__NR_getppid));
489 EXPECT_EQ(pid, syscall(__NR_getpid));
490 /* getpid() should never return. */
491 EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE));
492}
493
494/* TODO(wad) add 64-bit versus 32-bit arg tests. */
495TEST(arg_out_of_range)
496{
497 struct sock_filter filter[] = {
498 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(6)),
499 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
500 };
501 struct sock_fprog prog = {
502 .len = (unsigned short)ARRAY_SIZE(filter),
503 .filter = filter,
504 };
505 long ret;
506
507 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
508 ASSERT_EQ(0, ret);
509
510 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
511 EXPECT_EQ(-1, ret);
512 EXPECT_EQ(EINVAL, errno);
513}
514
515TEST(ERRNO_valid)
516{
517 struct sock_filter filter[] = {
518 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
519 offsetof(struct seccomp_data, nr)),
520 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
521 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | E2BIG),
522 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
523 };
524 struct sock_fprog prog = {
525 .len = (unsigned short)ARRAY_SIZE(filter),
526 .filter = filter,
527 };
528 long ret;
529 pid_t parent = getppid();
530
531 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
532 ASSERT_EQ(0, ret);
533
534 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
535 ASSERT_EQ(0, ret);
536
537 EXPECT_EQ(parent, syscall(__NR_getppid));
538 EXPECT_EQ(-1, read(0, NULL, 0));
539 EXPECT_EQ(E2BIG, errno);
540}
541
542TEST(ERRNO_zero)
543{
544 struct sock_filter filter[] = {
545 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
546 offsetof(struct seccomp_data, nr)),
547 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
548 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | 0),
549 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
550 };
551 struct sock_fprog prog = {
552 .len = (unsigned short)ARRAY_SIZE(filter),
553 .filter = filter,
554 };
555 long ret;
556 pid_t parent = getppid();
557
558 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
559 ASSERT_EQ(0, ret);
560
561 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
562 ASSERT_EQ(0, ret);
563
564 EXPECT_EQ(parent, syscall(__NR_getppid));
565 /* "errno" of 0 is ok. */
566 EXPECT_EQ(0, read(0, NULL, 0));
567}
568
569TEST(ERRNO_capped)
570{
571 struct sock_filter filter[] = {
572 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
573 offsetof(struct seccomp_data, nr)),
574 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
575 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | 4096),
576 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
577 };
578 struct sock_fprog prog = {
579 .len = (unsigned short)ARRAY_SIZE(filter),
580 .filter = filter,
581 };
582 long ret;
583 pid_t parent = getppid();
584
585 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
586 ASSERT_EQ(0, ret);
587
588 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
589 ASSERT_EQ(0, ret);
590
591 EXPECT_EQ(parent, syscall(__NR_getppid));
592 EXPECT_EQ(-1, read(0, NULL, 0));
593 EXPECT_EQ(4095, errno);
594}
595
596FIXTURE_DATA(TRAP) {
597 struct sock_fprog prog;
598};
599
600FIXTURE_SETUP(TRAP)
601{
602 struct sock_filter filter[] = {
603 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
604 offsetof(struct seccomp_data, nr)),
605 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),
606 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP),
607 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
608 };
609
610 memset(&self->prog, 0, sizeof(self->prog));
611 self->prog.filter = malloc(sizeof(filter));
612 ASSERT_NE(NULL, self->prog.filter);
613 memcpy(self->prog.filter, filter, sizeof(filter));
614 self->prog.len = (unsigned short)ARRAY_SIZE(filter);
615}
616
617FIXTURE_TEARDOWN(TRAP)
618{
619 if (self->prog.filter)
620 free(self->prog.filter);
621}
622
623TEST_F_SIGNAL(TRAP, dfl, SIGSYS)
624{
625 long ret;
626
627 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
628 ASSERT_EQ(0, ret);
629
630 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
631 ASSERT_EQ(0, ret);
632 syscall(__NR_getpid);
633}
634
635/* Ensure that SIGSYS overrides SIG_IGN */
636TEST_F_SIGNAL(TRAP, ign, SIGSYS)
637{
638 long ret;
639
640 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
641 ASSERT_EQ(0, ret);
642
643 signal(SIGSYS, SIG_IGN);
644
645 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
646 ASSERT_EQ(0, ret);
647 syscall(__NR_getpid);
648}
649
650static struct siginfo TRAP_info;
651static volatile int TRAP_nr;
652static void TRAP_action(int nr, siginfo_t *info, void *void_context)
653{
654 memcpy(&TRAP_info, info, sizeof(TRAP_info));
655 TRAP_nr = nr;
656}
657
658TEST_F(TRAP, handler)
659{
660 int ret, test;
661 struct sigaction act;
662 sigset_t mask;
663
664 memset(&act, 0, sizeof(act));
665 sigemptyset(&mask);
666 sigaddset(&mask, SIGSYS);
667
668 act.sa_sigaction = &TRAP_action;
669 act.sa_flags = SA_SIGINFO;
670 ret = sigaction(SIGSYS, &act, NULL);
671 ASSERT_EQ(0, ret) {
672 TH_LOG("sigaction failed");
673 }
674 ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
675 ASSERT_EQ(0, ret) {
676 TH_LOG("sigprocmask failed");
677 }
678
679 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
680 ASSERT_EQ(0, ret);
681 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
682 ASSERT_EQ(0, ret);
683 TRAP_nr = 0;
684 memset(&TRAP_info, 0, sizeof(TRAP_info));
685 /* Expect the registers to be rolled back. (nr = error) may vary
686 * based on arch. */
687 ret = syscall(__NR_getpid);
688 /* Silence gcc warning about volatile. */
689 test = TRAP_nr;
690 EXPECT_EQ(SIGSYS, test);
691 struct local_sigsys {
692 void *_call_addr; /* calling user insn */
693 int _syscall; /* triggering system call number */
694 unsigned int _arch; /* AUDIT_ARCH_* of syscall */
695 } *sigsys = (struct local_sigsys *)
696#ifdef si_syscall
697 &(TRAP_info.si_call_addr);
698#else
699 &TRAP_info.si_pid;
700#endif
701 EXPECT_EQ(__NR_getpid, sigsys->_syscall);
702 /* Make sure arch is non-zero. */
703 EXPECT_NE(0, sigsys->_arch);
704 EXPECT_NE(0, (unsigned long)sigsys->_call_addr);
705}
706
707FIXTURE_DATA(precedence) {
708 struct sock_fprog allow;
709 struct sock_fprog trace;
710 struct sock_fprog error;
711 struct sock_fprog trap;
712 struct sock_fprog kill;
713};
714
715FIXTURE_SETUP(precedence)
716{
717 struct sock_filter allow_insns[] = {
718 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
719 };
720 struct sock_filter trace_insns[] = {
721 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
722 offsetof(struct seccomp_data, nr)),
723 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
724 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
725 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE),
726 };
727 struct sock_filter error_insns[] = {
728 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
729 offsetof(struct seccomp_data, nr)),
730 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
731 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
732 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO),
733 };
734 struct sock_filter trap_insns[] = {
735 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
736 offsetof(struct seccomp_data, nr)),
737 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
738 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
739 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP),
740 };
741 struct sock_filter kill_insns[] = {
742 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
743 offsetof(struct seccomp_data, nr)),
744 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
745 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
746 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
747 };
748
749 memset(self, 0, sizeof(*self));
750#define FILTER_ALLOC(_x) \
751 self->_x.filter = malloc(sizeof(_x##_insns)); \
752 ASSERT_NE(NULL, self->_x.filter); \
753 memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \
754 self->_x.len = (unsigned short)ARRAY_SIZE(_x##_insns)
755 FILTER_ALLOC(allow);
756 FILTER_ALLOC(trace);
757 FILTER_ALLOC(error);
758 FILTER_ALLOC(trap);
759 FILTER_ALLOC(kill);
760}
761
762FIXTURE_TEARDOWN(precedence)
763{
764#define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter)
765 FILTER_FREE(allow);
766 FILTER_FREE(trace);
767 FILTER_FREE(error);
768 FILTER_FREE(trap);
769 FILTER_FREE(kill);
770}
771
772TEST_F(precedence, allow_ok)
773{
774 pid_t parent, res = 0;
775 long ret;
776
777 parent = getppid();
778 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
779 ASSERT_EQ(0, ret);
780
781 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
782 ASSERT_EQ(0, ret);
783 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
784 ASSERT_EQ(0, ret);
785 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
786 ASSERT_EQ(0, ret);
787 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
788 ASSERT_EQ(0, ret);
789 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
790 ASSERT_EQ(0, ret);
791 /* Should work just fine. */
792 res = syscall(__NR_getppid);
793 EXPECT_EQ(parent, res);
794}
795
796TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS)
797{
798 pid_t parent, res = 0;
799 long ret;
800
801 parent = getppid();
802 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
803 ASSERT_EQ(0, ret);
804
805 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
806 ASSERT_EQ(0, ret);
807 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
808 ASSERT_EQ(0, ret);
809 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
810 ASSERT_EQ(0, ret);
811 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
812 ASSERT_EQ(0, ret);
813 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
814 ASSERT_EQ(0, ret);
815 /* Should work just fine. */
816 res = syscall(__NR_getppid);
817 EXPECT_EQ(parent, res);
818 /* getpid() should never return. */
819 res = syscall(__NR_getpid);
820 EXPECT_EQ(0, res);
821}
822
823TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS)
824{
825 pid_t parent;
826 long ret;
827
828 parent = getppid();
829 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
830 ASSERT_EQ(0, ret);
831
832 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
833 ASSERT_EQ(0, ret);
834 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
835 ASSERT_EQ(0, ret);
836 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
837 ASSERT_EQ(0, ret);
838 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
839 ASSERT_EQ(0, ret);
840 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
841 ASSERT_EQ(0, ret);
842 /* Should work just fine. */
843 EXPECT_EQ(parent, syscall(__NR_getppid));
844 /* getpid() should never return. */
845 EXPECT_EQ(0, syscall(__NR_getpid));
846}
847
848TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS)
849{
850 pid_t parent;
851 long ret;
852
853 parent = getppid();
854 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
855 ASSERT_EQ(0, ret);
856
857 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
858 ASSERT_EQ(0, ret);
859 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
860 ASSERT_EQ(0, ret);
861 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
862 ASSERT_EQ(0, ret);
863 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
864 ASSERT_EQ(0, ret);
865 /* Should work just fine. */
866 EXPECT_EQ(parent, syscall(__NR_getppid));
867 /* getpid() should never return. */
868 EXPECT_EQ(0, syscall(__NR_getpid));
869}
870
871TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS)
872{
873 pid_t parent;
874 long ret;
875
876 parent = getppid();
877 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
878 ASSERT_EQ(0, ret);
879
880 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
881 ASSERT_EQ(0, ret);
882 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
883 ASSERT_EQ(0, ret);
884 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
885 ASSERT_EQ(0, ret);
886 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
887 ASSERT_EQ(0, ret);
888 /* Should work just fine. */
889 EXPECT_EQ(parent, syscall(__NR_getppid));
890 /* getpid() should never return. */
891 EXPECT_EQ(0, syscall(__NR_getpid));
892}
893
894TEST_F(precedence, errno_is_third)
895{
896 pid_t parent;
897 long ret;
898
899 parent = getppid();
900 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
901 ASSERT_EQ(0, ret);
902
903 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
904 ASSERT_EQ(0, ret);
905 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
906 ASSERT_EQ(0, ret);
907 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
908 ASSERT_EQ(0, ret);
909 /* Should work just fine. */
910 EXPECT_EQ(parent, syscall(__NR_getppid));
911 EXPECT_EQ(0, syscall(__NR_getpid));
912}
913
914TEST_F(precedence, errno_is_third_in_any_order)
915{
916 pid_t parent;
917 long ret;
918
919 parent = getppid();
920 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
921 ASSERT_EQ(0, ret);
922
923 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
924 ASSERT_EQ(0, ret);
925 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
926 ASSERT_EQ(0, ret);
927 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
928 ASSERT_EQ(0, ret);
929 /* Should work just fine. */
930 EXPECT_EQ(parent, syscall(__NR_getppid));
931 EXPECT_EQ(0, syscall(__NR_getpid));
932}
933
934TEST_F(precedence, trace_is_fourth)
935{
936 pid_t parent;
937 long ret;
938
939 parent = getppid();
940 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
941 ASSERT_EQ(0, ret);
942
943 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
944 ASSERT_EQ(0, ret);
945 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
946 ASSERT_EQ(0, ret);
947 /* Should work just fine. */
948 EXPECT_EQ(parent, syscall(__NR_getppid));
949 /* No ptracer */
950 EXPECT_EQ(-1, syscall(__NR_getpid));
951}
952
953TEST_F(precedence, trace_is_fourth_in_any_order)
954{
955 pid_t parent;
956 long ret;
957
958 parent = getppid();
959 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
960 ASSERT_EQ(0, ret);
961
962 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
963 ASSERT_EQ(0, ret);
964 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
965 ASSERT_EQ(0, ret);
966 /* Should work just fine. */
967 EXPECT_EQ(parent, syscall(__NR_getppid));
968 /* No ptracer */
969 EXPECT_EQ(-1, syscall(__NR_getpid));
970}
971
972#ifndef PTRACE_O_TRACESECCOMP
973#define PTRACE_O_TRACESECCOMP 0x00000080
974#endif
975
976/* Catch the Ubuntu 12.04 value error. */
977#if PTRACE_EVENT_SECCOMP != 7
978#undef PTRACE_EVENT_SECCOMP
979#endif
980
981#ifndef PTRACE_EVENT_SECCOMP
982#define PTRACE_EVENT_SECCOMP 7
983#endif
984
985#define IS_SECCOMP_EVENT(status) ((status >> 16) == PTRACE_EVENT_SECCOMP)
986bool tracer_running;
987void tracer_stop(int sig)
988{
989 tracer_running = false;
990}
991
992typedef void tracer_func_t(struct __test_metadata *_metadata,
993 pid_t tracee, int status, void *args);
994
995void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
996 tracer_func_t tracer_func, void *args)
997{
998 int ret = -1;
999 struct sigaction action = {
1000 .sa_handler = tracer_stop,
1001 };
1002
1003 /* Allow external shutdown. */
1004 tracer_running = true;
1005 ASSERT_EQ(0, sigaction(SIGUSR1, &action, NULL));
1006
1007 errno = 0;
1008 while (ret == -1 && errno != EINVAL)
1009 ret = ptrace(PTRACE_ATTACH, tracee, NULL, 0);
1010 ASSERT_EQ(0, ret) {
1011 kill(tracee, SIGKILL);
1012 }
1013 /* Wait for attach stop */
1014 wait(NULL);
1015
1016 ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, PTRACE_O_TRACESECCOMP);
1017 ASSERT_EQ(0, ret) {
1018 TH_LOG("Failed to set PTRACE_O_TRACESECCOMP");
1019 kill(tracee, SIGKILL);
1020 }
1021 ptrace(PTRACE_CONT, tracee, NULL, 0);
1022
1023 /* Unblock the tracee */
1024 ASSERT_EQ(1, write(fd, "A", 1));
1025 ASSERT_EQ(0, close(fd));
1026
1027 /* Run until we're shut down. Must assert to stop execution. */
1028 while (tracer_running) {
1029 int status;
1030
1031 if (wait(&status) != tracee)
1032 continue;
1033 if (WIFSIGNALED(status) || WIFEXITED(status))
1034 /* Child is dead. Time to go. */
1035 return;
1036
1037 /* Make sure this is a seccomp event. */
1038 ASSERT_EQ(true, IS_SECCOMP_EVENT(status));
1039
1040 tracer_func(_metadata, tracee, status, args);
1041
1042 ret = ptrace(PTRACE_CONT, tracee, NULL, NULL);
1043 ASSERT_EQ(0, ret);
1044 }
1045 /* Directly report the status of our test harness results. */
1046 syscall(__NR_exit, _metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
1047}
1048
1049/* Common tracer setup/teardown functions. */
1050void cont_handler(int num)
1051{ }
1052pid_t setup_trace_fixture(struct __test_metadata *_metadata,
1053 tracer_func_t func, void *args)
1054{
1055 char sync;
1056 int pipefd[2];
1057 pid_t tracer_pid;
1058 pid_t tracee = getpid();
1059
1060 /* Setup a pipe for clean synchronization. */
1061 ASSERT_EQ(0, pipe(pipefd));
1062
1063 /* Fork a child which we'll promote to tracer */
1064 tracer_pid = fork();
1065 ASSERT_LE(0, tracer_pid);
1066 signal(SIGALRM, cont_handler);
1067 if (tracer_pid == 0) {
1068 close(pipefd[0]);
1069 tracer(_metadata, pipefd[1], tracee, func, args);
1070 syscall(__NR_exit, 0);
1071 }
1072 close(pipefd[1]);
1073 prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0);
1074 read(pipefd[0], &sync, 1);
1075 close(pipefd[0]);
1076
1077 return tracer_pid;
1078}
1079void teardown_trace_fixture(struct __test_metadata *_metadata,
1080 pid_t tracer)
1081{
1082 if (tracer) {
1083 int status;
1084 /*
1085 * Extract the exit code from the other process and
1086 * adopt it for ourselves in case its asserts failed.
1087 */
1088 ASSERT_EQ(0, kill(tracer, SIGUSR1));
1089 ASSERT_EQ(tracer, waitpid(tracer, &status, 0));
1090 if (WEXITSTATUS(status))
1091 _metadata->passed = 0;
1092 }
1093}
1094
1095/* "poke" tracer arguments and function. */
1096struct tracer_args_poke_t {
1097 unsigned long poke_addr;
1098};
1099
1100void tracer_poke(struct __test_metadata *_metadata, pid_t tracee, int status,
1101 void *args)
1102{
1103 int ret;
1104 unsigned long msg;
1105 struct tracer_args_poke_t *info = (struct tracer_args_poke_t *)args;
1106
1107 ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
1108 EXPECT_EQ(0, ret);
1109 /* If this fails, don't try to recover. */
1110 ASSERT_EQ(0x1001, msg) {
1111 kill(tracee, SIGKILL);
1112 }
1113 /*
1114 * Poke in the message.
1115 * Registers are not touched to try to keep this relatively arch
1116 * agnostic.
1117 */
1118 ret = ptrace(PTRACE_POKEDATA, tracee, info->poke_addr, 0x1001);
1119 EXPECT_EQ(0, ret);
1120}
1121
1122FIXTURE_DATA(TRACE_poke) {
1123 struct sock_fprog prog;
1124 pid_t tracer;
1125 long poked;
1126 struct tracer_args_poke_t tracer_args;
1127};
1128
1129FIXTURE_SETUP(TRACE_poke)
1130{
1131 struct sock_filter filter[] = {
1132 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1133 offsetof(struct seccomp_data, nr)),
1134 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
1135 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1001),
1136 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1137 };
1138
1139 self->poked = 0;
1140 memset(&self->prog, 0, sizeof(self->prog));
1141 self->prog.filter = malloc(sizeof(filter));
1142 ASSERT_NE(NULL, self->prog.filter);
1143 memcpy(self->prog.filter, filter, sizeof(filter));
1144 self->prog.len = (unsigned short)ARRAY_SIZE(filter);
1145
1146 /* Set up tracer args. */
1147 self->tracer_args.poke_addr = (unsigned long)&self->poked;
1148
1149 /* Launch tracer. */
1150 self->tracer = setup_trace_fixture(_metadata, tracer_poke,
1151 &self->tracer_args);
1152}
1153
1154FIXTURE_TEARDOWN(TRACE_poke)
1155{
1156 teardown_trace_fixture(_metadata, self->tracer);
1157 if (self->prog.filter)
1158 free(self->prog.filter);
1159}
1160
1161TEST_F(TRACE_poke, read_has_side_effects)
1162{
1163 ssize_t ret;
1164
1165 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1166 ASSERT_EQ(0, ret);
1167
1168 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1169 ASSERT_EQ(0, ret);
1170
1171 EXPECT_EQ(0, self->poked);
1172 ret = read(-1, NULL, 0);
1173 EXPECT_EQ(-1, ret);
1174 EXPECT_EQ(0x1001, self->poked);
1175}
1176
1177TEST_F(TRACE_poke, getpid_runs_normally)
1178{
1179 long ret;
1180
1181 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1182 ASSERT_EQ(0, ret);
1183
1184 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1185 ASSERT_EQ(0, ret);
1186
1187 EXPECT_EQ(0, self->poked);
1188 EXPECT_NE(0, syscall(__NR_getpid));
1189 EXPECT_EQ(0, self->poked);
1190}
1191
1192#if defined(__x86_64__)
1193# define ARCH_REGS struct user_regs_struct
1194# define SYSCALL_NUM orig_rax
1195# define SYSCALL_RET rax
1196#elif defined(__i386__)
1197# define ARCH_REGS struct user_regs_struct
1198# define SYSCALL_NUM orig_eax
1199# define SYSCALL_RET eax
1200#elif defined(__arm__)
1201# define ARCH_REGS struct pt_regs
1202# define SYSCALL_NUM ARM_r7
1203# define SYSCALL_RET ARM_r0
1204#elif defined(__aarch64__)
1205# define ARCH_REGS struct user_pt_regs
1206# define SYSCALL_NUM regs[8]
1207# define SYSCALL_RET regs[0]
1208#else
1209# error "Do not know how to find your architecture's registers and syscalls"
1210#endif
1211
1212/* Architecture-specific syscall fetching routine. */
1213int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
1214{
1215 struct iovec iov;
1216 ARCH_REGS regs;
1217
1218 iov.iov_base = &regs;
1219 iov.iov_len = sizeof(regs);
1220 EXPECT_EQ(0, ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov)) {
1221 TH_LOG("PTRACE_GETREGSET failed");
1222 return -1;
1223 }
1224
1225 return regs.SYSCALL_NUM;
1226}
1227
1228/* Architecture-specific syscall changing routine. */
1229void change_syscall(struct __test_metadata *_metadata,
1230 pid_t tracee, int syscall)
1231{
1232 struct iovec iov;
1233 int ret;
1234 ARCH_REGS regs;
1235
1236 iov.iov_base = &regs;
1237 iov.iov_len = sizeof(regs);
1238 ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov);
1239 EXPECT_EQ(0, ret);
1240
1241#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__)
1242 {
1243 regs.SYSCALL_NUM = syscall;
1244 }
1245
1246#elif defined(__arm__)
1247# ifndef PTRACE_SET_SYSCALL
1248# define PTRACE_SET_SYSCALL 23
1249# endif
1250 {
1251 ret = ptrace(PTRACE_SET_SYSCALL, tracee, NULL, syscall);
1252 EXPECT_EQ(0, ret);
1253 }
1254
1255#else
1256 ASSERT_EQ(1, 0) {
1257 TH_LOG("How is the syscall changed on this architecture?");
1258 }
1259#endif
1260
1261 /* If syscall is skipped, change return value. */
1262 if (syscall == -1)
1263 regs.SYSCALL_RET = 1;
1264
1265 ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov);
1266 EXPECT_EQ(0, ret);
1267}
1268
1269void tracer_syscall(struct __test_metadata *_metadata, pid_t tracee,
1270 int status, void *args)
1271{
1272 int ret;
1273 unsigned long msg;
1274
1275 /* Make sure we got the right message. */
1276 ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
1277 EXPECT_EQ(0, ret);
1278
1279 switch (msg) {
1280 case 0x1002:
1281 /* change getpid to getppid. */
1282 change_syscall(_metadata, tracee, __NR_getppid);
1283 break;
1284 case 0x1003:
1285 /* skip gettid. */
1286 change_syscall(_metadata, tracee, -1);
1287 break;
1288 case 0x1004:
1289 /* do nothing (allow getppid) */
1290 break;
1291 default:
1292 EXPECT_EQ(0, msg) {
1293 TH_LOG("Unknown PTRACE_GETEVENTMSG: 0x%lx", msg);
1294 kill(tracee, SIGKILL);
1295 }
1296 }
1297
1298}
1299
1300FIXTURE_DATA(TRACE_syscall) {
1301 struct sock_fprog prog;
1302 pid_t tracer, mytid, mypid, parent;
1303};
1304
1305FIXTURE_SETUP(TRACE_syscall)
1306{
1307 struct sock_filter filter[] = {
1308 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1309 offsetof(struct seccomp_data, nr)),
1310 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),
1311 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1002),
1312 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_gettid, 0, 1),
1313 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1003),
1314 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1315 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1004),
1316 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1317 };
1318
1319 memset(&self->prog, 0, sizeof(self->prog));
1320 self->prog.filter = malloc(sizeof(filter));
1321 ASSERT_NE(NULL, self->prog.filter);
1322 memcpy(self->prog.filter, filter, sizeof(filter));
1323 self->prog.len = (unsigned short)ARRAY_SIZE(filter);
1324
1325 /* Prepare some testable syscall results. */
1326 self->mytid = syscall(__NR_gettid);
1327 ASSERT_GT(self->mytid, 0);
1328 ASSERT_NE(self->mytid, 1) {
1329 TH_LOG("Running this test as init is not supported. :)");
1330 }
1331
1332 self->mypid = getpid();
1333 ASSERT_GT(self->mypid, 0);
1334 ASSERT_EQ(self->mytid, self->mypid);
1335
1336 self->parent = getppid();
1337 ASSERT_GT(self->parent, 0);
1338 ASSERT_NE(self->parent, self->mypid);
1339
1340 /* Launch tracer. */
1341 self->tracer = setup_trace_fixture(_metadata, tracer_syscall, NULL);
1342}
1343
1344FIXTURE_TEARDOWN(TRACE_syscall)
1345{
1346 teardown_trace_fixture(_metadata, self->tracer);
1347 if (self->prog.filter)
1348 free(self->prog.filter);
1349}
1350
1351TEST_F(TRACE_syscall, syscall_allowed)
1352{
1353 long ret;
1354
1355 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1356 ASSERT_EQ(0, ret);
1357
1358 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1359 ASSERT_EQ(0, ret);
1360
1361 /* getppid works as expected (no changes). */
1362 EXPECT_EQ(self->parent, syscall(__NR_getppid));
1363 EXPECT_NE(self->mypid, syscall(__NR_getppid));
1364}
1365
1366TEST_F(TRACE_syscall, syscall_redirected)
1367{
1368 long ret;
1369
1370 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1371 ASSERT_EQ(0, ret);
1372
1373 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1374 ASSERT_EQ(0, ret);
1375
1376 /* getpid has been redirected to getppid as expected. */
1377 EXPECT_EQ(self->parent, syscall(__NR_getpid));
1378 EXPECT_NE(self->mypid, syscall(__NR_getpid));
1379}
1380
1381TEST_F(TRACE_syscall, syscall_dropped)
1382{
1383 long ret;
1384
1385 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1386 ASSERT_EQ(0, ret);
1387
1388 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1389 ASSERT_EQ(0, ret);
1390
1391 /* gettid has been skipped and an altered return value stored. */
1392 EXPECT_EQ(1, syscall(__NR_gettid));
1393 EXPECT_NE(self->mytid, syscall(__NR_gettid));
1394}
1395
1396#ifndef __NR_seccomp
1397# if defined(__i386__)
1398# define __NR_seccomp 354
1399# elif defined(__x86_64__)
1400# define __NR_seccomp 317
1401# elif defined(__arm__)
1402# define __NR_seccomp 383
1403# elif defined(__aarch64__)
1404# define __NR_seccomp 277
1405# else
1406# warning "seccomp syscall number unknown for this architecture"
1407# define __NR_seccomp 0xffff
1408# endif
1409#endif
1410
1411#ifndef SECCOMP_SET_MODE_STRICT
1412#define SECCOMP_SET_MODE_STRICT 0
1413#endif
1414
1415#ifndef SECCOMP_SET_MODE_FILTER
1416#define SECCOMP_SET_MODE_FILTER 1
1417#endif
1418
1419#ifndef SECCOMP_FLAG_FILTER_TSYNC
1420#define SECCOMP_FLAG_FILTER_TSYNC 1
1421#endif
1422
1423#ifndef seccomp
1424int seccomp(unsigned int op, unsigned int flags, struct sock_fprog *filter)
1425{
1426 errno = 0;
1427 return syscall(__NR_seccomp, op, flags, filter);
1428}
1429#endif
1430
1431TEST(seccomp_syscall)
1432{
1433 struct sock_filter filter[] = {
1434 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1435 };
1436 struct sock_fprog prog = {
1437 .len = (unsigned short)ARRAY_SIZE(filter),
1438 .filter = filter,
1439 };
1440 long ret;
1441
1442 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1443 ASSERT_EQ(0, ret) {
1444 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1445 }
1446
1447 /* Reject insane operation. */
1448 ret = seccomp(-1, 0, &prog);
1449 EXPECT_EQ(EINVAL, errno) {
1450 TH_LOG("Did not reject crazy op value!");
1451 }
1452
1453 /* Reject strict with flags or pointer. */
1454 ret = seccomp(SECCOMP_SET_MODE_STRICT, -1, NULL);
1455 EXPECT_EQ(EINVAL, errno) {
1456 TH_LOG("Did not reject mode strict with flags!");
1457 }
1458 ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, &prog);
1459 EXPECT_EQ(EINVAL, errno) {
1460 TH_LOG("Did not reject mode strict with uargs!");
1461 }
1462
1463 /* Reject insane args for filter. */
1464 ret = seccomp(SECCOMP_SET_MODE_FILTER, -1, &prog);
1465 EXPECT_EQ(EINVAL, errno) {
1466 TH_LOG("Did not reject crazy filter flags!");
1467 }
1468 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, NULL);
1469 EXPECT_EQ(EFAULT, errno) {
1470 TH_LOG("Did not reject NULL filter!");
1471 }
1472
1473 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
1474 EXPECT_EQ(0, errno) {
1475 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER: %s",
1476 strerror(errno));
1477 }
1478}
1479
1480TEST(seccomp_syscall_mode_lock)
1481{
1482 struct sock_filter filter[] = {
1483 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1484 };
1485 struct sock_fprog prog = {
1486 .len = (unsigned short)ARRAY_SIZE(filter),
1487 .filter = filter,
1488 };
1489 long ret;
1490
1491 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
1492 ASSERT_EQ(0, ret) {
1493 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1494 }
1495
1496 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
1497 EXPECT_EQ(0, ret) {
1498 TH_LOG("Could not install filter!");
1499 }
1500
1501 /* Make sure neither entry point will switch to strict. */
1502 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, 0, 0, 0);
1503 EXPECT_EQ(EINVAL, errno) {
1504 TH_LOG("Switched to mode strict!");
1505 }
1506
1507 ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, NULL);
1508 EXPECT_EQ(EINVAL, errno) {
1509 TH_LOG("Switched to mode strict!");
1510 }
1511}
1512
1513TEST(TSYNC_first)
1514{
1515 struct sock_filter filter[] = {
1516 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1517 };
1518 struct sock_fprog prog = {
1519 .len = (unsigned short)ARRAY_SIZE(filter),
1520 .filter = filter,
1521 };
1522 long ret;
1523
1524 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
1525 ASSERT_EQ(0, ret) {
1526 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1527 }
1528
1529 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1530 &prog);
1531 EXPECT_EQ(0, ret) {
1532 TH_LOG("Could not install initial filter with TSYNC!");
1533 }
1534}
1535
1536#define TSYNC_SIBLINGS 2
1537struct tsync_sibling {
1538 pthread_t tid;
1539 pid_t system_tid;
1540 sem_t *started;
1541 pthread_cond_t *cond;
1542 pthread_mutex_t *mutex;
1543 int diverge;
1544 int num_waits;
1545 struct sock_fprog *prog;
1546 struct __test_metadata *metadata;
1547};
1548
1549FIXTURE_DATA(TSYNC) {
1550 struct sock_fprog root_prog, apply_prog;
1551 struct tsync_sibling sibling[TSYNC_SIBLINGS];
1552 sem_t started;
1553 pthread_cond_t cond;
1554 pthread_mutex_t mutex;
1555 int sibling_count;
1556};
1557
1558FIXTURE_SETUP(TSYNC)
1559{
1560 struct sock_filter root_filter[] = {
1561 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1562 };
1563 struct sock_filter apply_filter[] = {
1564 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1565 offsetof(struct seccomp_data, nr)),
1566 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
1567 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
1568 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1569 };
1570
1571 memset(&self->root_prog, 0, sizeof(self->root_prog));
1572 memset(&self->apply_prog, 0, sizeof(self->apply_prog));
1573 memset(&self->sibling, 0, sizeof(self->sibling));
1574 self->root_prog.filter = malloc(sizeof(root_filter));
1575 ASSERT_NE(NULL, self->root_prog.filter);
1576 memcpy(self->root_prog.filter, &root_filter, sizeof(root_filter));
1577 self->root_prog.len = (unsigned short)ARRAY_SIZE(root_filter);
1578
1579 self->apply_prog.filter = malloc(sizeof(apply_filter));
1580 ASSERT_NE(NULL, self->apply_prog.filter);
1581 memcpy(self->apply_prog.filter, &apply_filter, sizeof(apply_filter));
1582 self->apply_prog.len = (unsigned short)ARRAY_SIZE(apply_filter);
1583
1584 self->sibling_count = 0;
1585 pthread_mutex_init(&self->mutex, NULL);
1586 pthread_cond_init(&self->cond, NULL);
1587 sem_init(&self->started, 0, 0);
1588 self->sibling[0].tid = 0;
1589 self->sibling[0].cond = &self->cond;
1590 self->sibling[0].started = &self->started;
1591 self->sibling[0].mutex = &self->mutex;
1592 self->sibling[0].diverge = 0;
1593 self->sibling[0].num_waits = 1;
1594 self->sibling[0].prog = &self->root_prog;
1595 self->sibling[0].metadata = _metadata;
1596 self->sibling[1].tid = 0;
1597 self->sibling[1].cond = &self->cond;
1598 self->sibling[1].started = &self->started;
1599 self->sibling[1].mutex = &self->mutex;
1600 self->sibling[1].diverge = 0;
1601 self->sibling[1].prog = &self->root_prog;
1602 self->sibling[1].num_waits = 1;
1603 self->sibling[1].metadata = _metadata;
1604}
1605
1606FIXTURE_TEARDOWN(TSYNC)
1607{
1608 int sib = 0;
1609
1610 if (self->root_prog.filter)
1611 free(self->root_prog.filter);
1612 if (self->apply_prog.filter)
1613 free(self->apply_prog.filter);
1614
1615 for ( ; sib < self->sibling_count; ++sib) {
1616 struct tsync_sibling *s = &self->sibling[sib];
1617 void *status;
1618
1619 if (!s->tid)
1620 continue;
1621 if (pthread_kill(s->tid, 0)) {
1622 pthread_cancel(s->tid);
1623 pthread_join(s->tid, &status);
1624 }
1625 }
1626 pthread_mutex_destroy(&self->mutex);
1627 pthread_cond_destroy(&self->cond);
1628 sem_destroy(&self->started);
1629}
1630
1631void *tsync_sibling(void *data)
1632{
1633 long ret = 0;
1634 struct tsync_sibling *me = data;
1635
1636 me->system_tid = syscall(__NR_gettid);
1637
1638 pthread_mutex_lock(me->mutex);
1639 if (me->diverge) {
1640 /* Just re-apply the root prog to fork the tree */
1641 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER,
1642 me->prog, 0, 0);
1643 }
1644 sem_post(me->started);
1645 /* Return outside of started so parent notices failures. */
1646 if (ret) {
1647 pthread_mutex_unlock(me->mutex);
1648 return (void *)SIBLING_EXIT_FAILURE;
1649 }
1650 do {
1651 pthread_cond_wait(me->cond, me->mutex);
1652 me->num_waits = me->num_waits - 1;
1653 } while (me->num_waits);
1654 pthread_mutex_unlock(me->mutex);
1655
1656 ret = prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);
1657 if (!ret)
1658 return (void *)SIBLING_EXIT_NEWPRIVS;
1659 read(0, NULL, 0);
1660 return (void *)SIBLING_EXIT_UNKILLED;
1661}
1662
1663void tsync_start_sibling(struct tsync_sibling *sibling)
1664{
1665 pthread_create(&sibling->tid, NULL, tsync_sibling, (void *)sibling);
1666}
1667
1668TEST_F(TSYNC, siblings_fail_prctl)
1669{
1670 long ret;
1671 void *status;
1672 struct sock_filter filter[] = {
1673 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1674 offsetof(struct seccomp_data, nr)),
1675 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_prctl, 0, 1),
1676 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EINVAL),
1677 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1678 };
1679 struct sock_fprog prog = {
1680 .len = (unsigned short)ARRAY_SIZE(filter),
1681 .filter = filter,
1682 };
1683
1684 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
1685 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1686 }
1687
1688 /* Check prctl failure detection by requesting sib 0 diverge. */
1689 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
1690 ASSERT_EQ(0, ret) {
1691 TH_LOG("setting filter failed");
1692 }
1693
1694 self->sibling[0].diverge = 1;
1695 tsync_start_sibling(&self->sibling[0]);
1696 tsync_start_sibling(&self->sibling[1]);
1697
1698 while (self->sibling_count < TSYNC_SIBLINGS) {
1699 sem_wait(&self->started);
1700 self->sibling_count++;
1701 }
1702
1703 /* Signal the threads to clean up*/
1704 pthread_mutex_lock(&self->mutex);
1705 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1706 TH_LOG("cond broadcast non-zero");
1707 }
1708 pthread_mutex_unlock(&self->mutex);
1709
1710 /* Ensure diverging sibling failed to call prctl. */
1711 pthread_join(self->sibling[0].tid, &status);
1712 EXPECT_EQ(SIBLING_EXIT_FAILURE, (long)status);
1713 pthread_join(self->sibling[1].tid, &status);
1714 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1715}
1716
1717TEST_F(TSYNC, two_siblings_with_ancestor)
1718{
1719 long ret;
1720 void *status;
1721
1722 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
1723 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1724 }
1725
1726 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
1727 ASSERT_EQ(0, ret) {
1728 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
1729 }
1730 tsync_start_sibling(&self->sibling[0]);
1731 tsync_start_sibling(&self->sibling[1]);
1732
1733 while (self->sibling_count < TSYNC_SIBLINGS) {
1734 sem_wait(&self->started);
1735 self->sibling_count++;
1736 }
1737
1738 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1739 &self->apply_prog);
1740 ASSERT_EQ(0, ret) {
1741 TH_LOG("Could install filter on all threads!");
1742 }
1743 /* Tell the siblings to test the policy */
1744 pthread_mutex_lock(&self->mutex);
1745 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1746 TH_LOG("cond broadcast non-zero");
1747 }
1748 pthread_mutex_unlock(&self->mutex);
1749 /* Ensure they are both killed and don't exit cleanly. */
1750 pthread_join(self->sibling[0].tid, &status);
1751 EXPECT_EQ(0x0, (long)status);
1752 pthread_join(self->sibling[1].tid, &status);
1753 EXPECT_EQ(0x0, (long)status);
1754}
1755
1756TEST_F(TSYNC, two_sibling_want_nnp)
1757{
1758 void *status;
1759
1760 /* start siblings before any prctl() operations */
1761 tsync_start_sibling(&self->sibling[0]);
1762 tsync_start_sibling(&self->sibling[1]);
1763 while (self->sibling_count < TSYNC_SIBLINGS) {
1764 sem_wait(&self->started);
1765 self->sibling_count++;
1766 }
1767
1768 /* Tell the siblings to test no policy */
1769 pthread_mutex_lock(&self->mutex);
1770 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1771 TH_LOG("cond broadcast non-zero");
1772 }
1773 pthread_mutex_unlock(&self->mutex);
1774
1775 /* Ensure they are both upset about lacking nnp. */
1776 pthread_join(self->sibling[0].tid, &status);
1777 EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);
1778 pthread_join(self->sibling[1].tid, &status);
1779 EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);
1780}
1781
1782TEST_F(TSYNC, two_siblings_with_no_filter)
1783{
1784 long ret;
1785 void *status;
1786
1787 /* start siblings before any prctl() operations */
1788 tsync_start_sibling(&self->sibling[0]);
1789 tsync_start_sibling(&self->sibling[1]);
1790 while (self->sibling_count < TSYNC_SIBLINGS) {
1791 sem_wait(&self->started);
1792 self->sibling_count++;
1793 }
1794
1795 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
1796 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1797 }
1798
1799 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1800 &self->apply_prog);
1801 ASSERT_EQ(0, ret) {
1802 TH_LOG("Could install filter on all threads!");
1803 }
1804
1805 /* Tell the siblings to test the policy */
1806 pthread_mutex_lock(&self->mutex);
1807 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1808 TH_LOG("cond broadcast non-zero");
1809 }
1810 pthread_mutex_unlock(&self->mutex);
1811
1812 /* Ensure they are both killed and don't exit cleanly. */
1813 pthread_join(self->sibling[0].tid, &status);
1814 EXPECT_EQ(0x0, (long)status);
1815 pthread_join(self->sibling[1].tid, &status);
1816 EXPECT_EQ(0x0, (long)status);
1817}
1818
1819TEST_F(TSYNC, two_siblings_with_one_divergence)
1820{
1821 long ret;
1822 void *status;
1823
1824 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
1825 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1826 }
1827
1828 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
1829 ASSERT_EQ(0, ret) {
1830 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
1831 }
1832 self->sibling[0].diverge = 1;
1833 tsync_start_sibling(&self->sibling[0]);
1834 tsync_start_sibling(&self->sibling[1]);
1835
1836 while (self->sibling_count < TSYNC_SIBLINGS) {
1837 sem_wait(&self->started);
1838 self->sibling_count++;
1839 }
1840
1841 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1842 &self->apply_prog);
1843 ASSERT_EQ(self->sibling[0].system_tid, ret) {
1844 TH_LOG("Did not fail on diverged sibling.");
1845 }
1846
1847 /* Wake the threads */
1848 pthread_mutex_lock(&self->mutex);
1849 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1850 TH_LOG("cond broadcast non-zero");
1851 }
1852 pthread_mutex_unlock(&self->mutex);
1853
1854 /* Ensure they are both unkilled. */
1855 pthread_join(self->sibling[0].tid, &status);
1856 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1857 pthread_join(self->sibling[1].tid, &status);
1858 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1859}
1860
1861TEST_F(TSYNC, two_siblings_not_under_filter)
1862{
1863 long ret, sib;
1864 void *status;
1865
1866 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
1867 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1868 }
1869
1870 /*
1871 * Sibling 0 will have its own seccomp policy
1872 * and Sibling 1 will not be under seccomp at
1873 * all. Sibling 1 will enter seccomp and 0
1874 * will cause failure.
1875 */
1876 self->sibling[0].diverge = 1;
1877 tsync_start_sibling(&self->sibling[0]);
1878 tsync_start_sibling(&self->sibling[1]);
1879
1880 while (self->sibling_count < TSYNC_SIBLINGS) {
1881 sem_wait(&self->started);
1882 self->sibling_count++;
1883 }
1884
1885 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
1886 ASSERT_EQ(0, ret) {
1887 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
1888 }
1889
1890 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1891 &self->apply_prog);
1892 ASSERT_EQ(ret, self->sibling[0].system_tid) {
1893 TH_LOG("Did not fail on diverged sibling.");
1894 }
1895 sib = 1;
1896 if (ret == self->sibling[0].system_tid)
1897 sib = 0;
1898
1899 pthread_mutex_lock(&self->mutex);
1900
1901 /* Increment the other siblings num_waits so we can clean up
1902 * the one we just saw.
1903 */
1904 self->sibling[!sib].num_waits += 1;
1905
1906 /* Signal the thread to clean up*/
1907 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1908 TH_LOG("cond broadcast non-zero");
1909 }
1910 pthread_mutex_unlock(&self->mutex);
1911 pthread_join(self->sibling[sib].tid, &status);
1912 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1913 /* Poll for actual task death. pthread_join doesn't guarantee it. */
1914 while (!kill(self->sibling[sib].system_tid, 0))
1915 sleep(0.1);
1916 /* Switch to the remaining sibling */
1917 sib = !sib;
1918
1919 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1920 &self->apply_prog);
1921 ASSERT_EQ(0, ret) {
1922 TH_LOG("Expected the remaining sibling to sync");
1923 };
1924
1925 pthread_mutex_lock(&self->mutex);
1926
1927 /* If remaining sibling didn't have a chance to wake up during
1928 * the first broadcast, manually reduce the num_waits now.
1929 */
1930 if (self->sibling[sib].num_waits > 1)
1931 self->sibling[sib].num_waits = 1;
1932 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1933 TH_LOG("cond broadcast non-zero");
1934 }
1935 pthread_mutex_unlock(&self->mutex);
1936 pthread_join(self->sibling[sib].tid, &status);
1937 EXPECT_EQ(0, (long)status);
1938 /* Poll for actual task death. pthread_join doesn't guarantee it. */
1939 while (!kill(self->sibling[sib].system_tid, 0))
1940 sleep(0.1);
1941
1942 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1943 &self->apply_prog);
1944 ASSERT_EQ(0, ret); /* just us chickens */
1945}
1946
1947/* Make sure restarted syscalls are seen directly as "restart_syscall". */
1948TEST(syscall_restart)
1949{
1950 long ret;
1951 unsigned long msg;
1952 pid_t child_pid;
1953 int pipefd[2];
1954 int status;
1955 siginfo_t info = { };
1956 struct sock_filter filter[] = {
1957 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1958 offsetof(struct seccomp_data, nr)),
1959
1960#ifdef __NR_sigreturn
1961 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_sigreturn, 6, 0),
1962#endif
1963 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 5, 0),
1964 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 4, 0),
1965 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 3, 0),
1966 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_poll, 4, 0),
1967 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0),
1968
1969 /* Allow __NR_write for easy logging. */
1970 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_write, 0, 1),
1971 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1972 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
1973 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100), /* poll */
1974 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200), /* restart */
1975 };
1976 struct sock_fprog prog = {
1977 .len = (unsigned short)ARRAY_SIZE(filter),
1978 .filter = filter,
1979 };
1980
1981 ASSERT_EQ(0, pipe(pipefd));
1982
1983 child_pid = fork();
1984 ASSERT_LE(0, child_pid);
1985 if (child_pid == 0) {
1986 /* Child uses EXPECT not ASSERT to deliver status correctly. */
1987 char buf = ' ';
1988 struct pollfd fds = {
1989 .fd = pipefd[0],
1990 .events = POLLIN,
1991 };
1992
1993 /* Attach parent as tracer and stop. */
1994 EXPECT_EQ(0, ptrace(PTRACE_TRACEME));
1995 EXPECT_EQ(0, raise(SIGSTOP));
1996
1997 EXPECT_EQ(0, close(pipefd[1]));
1998
1999 EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
2000 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
2001 }
2002
2003 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
2004 EXPECT_EQ(0, ret) {
2005 TH_LOG("Failed to install filter!");
2006 }
2007
2008 EXPECT_EQ(1, read(pipefd[0], &buf, 1)) {
2009 TH_LOG("Failed to read() sync from parent");
2010 }
2011 EXPECT_EQ('.', buf) {
2012 TH_LOG("Failed to get sync data from read()");
2013 }
2014
2015 /* Start poll to be interrupted. */
2016 errno = 0;
2017 EXPECT_EQ(1, poll(&fds, 1, -1)) {
2018 TH_LOG("Call to poll() failed (errno %d)", errno);
2019 }
2020
2021 /* Read final sync from parent. */
2022 EXPECT_EQ(1, read(pipefd[0], &buf, 1)) {
2023 TH_LOG("Failed final read() from parent");
2024 }
2025 EXPECT_EQ('!', buf) {
2026 TH_LOG("Failed to get final data from read()");
2027 }
2028
2029 /* Directly report the status of our test harness results. */
2030 syscall(__NR_exit, _metadata->passed ? EXIT_SUCCESS
2031 : EXIT_FAILURE);
2032 }
2033 EXPECT_EQ(0, close(pipefd[0]));
2034
2035 /* Attach to child, setup options, and release. */
2036 ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
2037 ASSERT_EQ(true, WIFSTOPPED(status));
2038 ASSERT_EQ(0, ptrace(PTRACE_SETOPTIONS, child_pid, NULL,
2039 PTRACE_O_TRACESECCOMP));
2040 ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
2041 ASSERT_EQ(1, write(pipefd[1], ".", 1));
2042
2043 /* Wait for poll() to start. */
2044 ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
2045 ASSERT_EQ(true, WIFSTOPPED(status));
2046 ASSERT_EQ(SIGTRAP, WSTOPSIG(status));
2047 ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
2048 ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
2049 ASSERT_EQ(0x100, msg);
2050 EXPECT_EQ(__NR_poll, get_syscall(_metadata, child_pid));
2051
2052 /* Might as well check siginfo for sanity while we're here. */
2053 ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
2054 ASSERT_EQ(SIGTRAP, info.si_signo);
2055 ASSERT_EQ(SIGTRAP | (PTRACE_EVENT_SECCOMP << 8), info.si_code);
2056 EXPECT_EQ(0, info.si_errno);
2057 EXPECT_EQ(getuid(), info.si_uid);
2058 /* Verify signal delivery came from child (seccomp-triggered). */
2059 EXPECT_EQ(child_pid, info.si_pid);
2060
2061 /* Interrupt poll with SIGSTOP (which we'll need to handle). */
2062 ASSERT_EQ(0, kill(child_pid, SIGSTOP));
2063 ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
2064 ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
2065 ASSERT_EQ(true, WIFSTOPPED(status));
2066 ASSERT_EQ(SIGSTOP, WSTOPSIG(status));
2067 /* Verify signal delivery came from parent now. */
2068 ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
2069 EXPECT_EQ(getpid(), info.si_pid);
2070
2071 /* Restart poll with SIGCONT, which triggers restart_syscall. */
2072 ASSERT_EQ(0, kill(child_pid, SIGCONT));
2073 ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
2074 ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
2075 ASSERT_EQ(true, WIFSTOPPED(status));
2076 ASSERT_EQ(SIGCONT, WSTOPSIG(status));
2077 ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
2078
2079 /* Wait for restart_syscall() to start. */
2080 ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
2081 ASSERT_EQ(true, WIFSTOPPED(status));
2082 ASSERT_EQ(SIGTRAP, WSTOPSIG(status));
2083 ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
2084 ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
2085 ASSERT_EQ(0x200, msg);
2086 ret = get_syscall(_metadata, child_pid);
2087#if defined(__arm__)
2088 /* FIXME: ARM does not expose true syscall in registers. */
2089 EXPECT_EQ(__NR_poll, ret);
2090#else
2091 EXPECT_EQ(__NR_restart_syscall, ret);
2092#endif
2093
2094 /* Write again to end poll. */
2095 ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
2096 ASSERT_EQ(1, write(pipefd[1], "!", 1));
2097 EXPECT_EQ(0, close(pipefd[1]));
2098
2099 ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
2100 if (WIFSIGNALED(status) || WEXITSTATUS(status))
2101 _metadata->passed = 0;
2102}
2103
2104/*
2105 * TODO:
2106 * - add microbenchmarks
2107 * - expand NNP testing
2108 * - better arch-specific TRACE and TRAP handlers.
2109 * - endianness checking when appropriate
2110 * - 64-bit arg prodding
2111 * - arch value testing (x86 modes especially)
2112 * - ...
2113 */
2114
2115TEST_HARNESS_MAIN