1 /* seccomp_bpf_tests.c
2 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 *
6 * Test code for seccomp bpf.
7 */
8
9 /* Need to include sys/types.h before asm/siginfo.h such that clock_t, pid_t,
10 * and timer_t are defined. */
11 #include <sys/types.h>
12 #include <asm/siginfo.h>
13 #define __have_siginfo_t 1
14 #define __have_sigval_t 1
15 #define __have_sigevent_t 1
16
17 #include <errno.h>
18 #include <linux/filter.h>
19 #include <linux/prctl.h>
20 #include <linux/ptrace.h>
21 #include <linux/seccomp.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 <syscall.h>
29
30 #define _GNU_SOURCE
31 #include <unistd.h>
32 #include <sys/syscall.h>
33
34 #include "test_harness.h"
35
36 #ifndef PR_SET_PTRACER
37 # define PR_SET_PTRACER 0x59616d61
38 #endif
39
40 #ifndef PR_SET_NO_NEW_PRIVS
41 #define PR_SET_NO_NEW_PRIVS 38
42 #define PR_GET_NO_NEW_PRIVS 39
43 #endif
44
45 #ifndef PR_SECCOMP_EXT
46 #define PR_SECCOMP_EXT 43
47 #endif
48
49 #ifndef SECCOMP_EXT_ACT
50 #define SECCOMP_EXT_ACT 1
51 #endif
52
53 #ifndef SECCOMP_EXT_ACT_TSYNC
54 #define SECCOMP_EXT_ACT_TSYNC 1
55 #endif
56
57 #ifndef SECCOMP_MODE_STRICT
58 #define SECCOMP_MODE_STRICT 1
59 #endif
60
61 #ifndef SECCOMP_MODE_FILTER
62 #define SECCOMP_MODE_FILTER 2
63 #endif
64
65 #ifndef SECCOMP_RET_KILL
66 #define SECCOMP_RET_KILL 0x00000000U // kill the task immediately
67 #define SECCOMP_RET_TRAP 0x00030000U // disallow and force a SIGSYS
68 #define SECCOMP_RET_ERRNO 0x00050000U // returns an errno
69 #define SECCOMP_RET_TRACE 0x7ff00000U // pass to a tracer or disallow
70 #define SECCOMP_RET_ALLOW 0x7fff0000U // allow
71
72 /* Masks for the return value sections. */
73 #define SECCOMP_RET_ACTION 0x7fff0000U
74 #define SECCOMP_RET_DATA 0x0000ffffU
75
76 struct seccomp_data {
77 int nr;
78 __u32 arch;
79 __u64 instruction_pointer;
80 __u64 args[6];
81 };
82 #endif
83
84 #define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
85
86 #define SIBLING_EXIT_UNKILLED 0xbadbeef
87 #define SIBLING_EXIT_FAILURE 0xbadface
88
TEST(mode_strict_support)89 TEST(mode_strict_support) {
90 long ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);
91 ASSERT_EQ(0, ret) {
92 TH_LOG("Kernel does not support CONFIG_SECCOMP");
93 }
94 syscall(__NR_exit, 1);
95 }
96
TEST_SIGNAL(mode_strict_cannot_call_prctl,SIGKILL)97 TEST_SIGNAL(mode_strict_cannot_call_prctl, SIGKILL) {
98 long ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);
99 ASSERT_EQ(0, ret) {
100 TH_LOG("Kernel does not support CONFIG_SECCOMP");
101 }
102 syscall(__NR_prctl, PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, NULL, NULL);
103 EXPECT_FALSE(true) {
104 TH_LOG("Unreachable!");
105 }
106 }
107
108 /* Note! This doesn't test no new privs behavior */
TEST(no_new_privs_support)109 TEST(no_new_privs_support) {
110 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
111 EXPECT_EQ(0, ret) {
112 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
113 }
114 }
115
116 /* Tests kernel support by checking for a copy_from_user() fault on * NULL. */
TEST(mode_filter_support)117 TEST(mode_filter_support) {
118 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
119 ASSERT_EQ(0, ret) {
120 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
121 }
122 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, NULL, NULL);
123 EXPECT_EQ(-1, ret);
124 EXPECT_EQ(EFAULT, errno) {
125 TH_LOG("Kernel does not support CONFIG_SECCOMP_FILTER!");
126 }
127 }
128
TEST(mode_filter_without_nnp)129 TEST(mode_filter_without_nnp) {
130 struct sock_filter filter[] = {
131 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
132 };
133 struct sock_fprog prog = {
134 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
135 .filter = filter,
136 };
137 long ret = prctl(PR_GET_NO_NEW_PRIVS, 0, NULL, 0, 0);
138 ASSERT_LE(0, ret) {
139 TH_LOG("Expected 0 or unsupported for NO_NEW_PRIVS");
140 }
141 errno = 0;
142 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
143 /* Succeeds with CAP_SYS_ADMIN, fails without */
144 /* TODO(wad) check caps not euid */
145 if (geteuid()) {
146 EXPECT_EQ(-1, ret);
147 EXPECT_EQ(EACCES, errno);
148 } else {
149 EXPECT_EQ(0, ret);
150 }
151 }
152
TEST(mode_filter_cannot_move_to_strict)153 TEST(mode_filter_cannot_move_to_strict) {
154 struct sock_filter filter[] = {
155 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
156 };
157 struct sock_fprog prog = {
158 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
159 .filter = filter,
160 };
161
162 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
163 ASSERT_EQ(0, ret);
164
165 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
166 ASSERT_EQ(0, ret);
167
168 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, 0, 0);
169 EXPECT_EQ(-1, ret);
170 EXPECT_EQ(EINVAL, errno);
171 }
172
173
TEST(ALLOW_all)174 TEST(ALLOW_all) {
175 struct sock_filter filter[] = {
176 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
177 };
178 struct sock_fprog prog = {
179 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
180 .filter = filter,
181 };
182
183 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
184 ASSERT_EQ(0, ret);
185
186 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
187 ASSERT_EQ(0, ret);
188 }
189
TEST(empty_prog)190 TEST(empty_prog) {
191 struct sock_filter filter[] = {
192 };
193 struct sock_fprog prog = {
194 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
195 .filter = filter,
196 };
197
198 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
199 ASSERT_EQ(0, ret);
200
201 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
202 EXPECT_EQ(-1, ret);
203 EXPECT_EQ(EINVAL, errno);
204 }
205
TEST_SIGNAL(unknown_ret_is_kill_inside,SIGSYS)206 TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS) {
207 struct sock_filter filter[] = {
208 BPF_STMT(BPF_RET+BPF_K, 0x10000000U),
209 };
210 struct sock_fprog prog = {
211 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
212 .filter = filter,
213 };
214
215 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
216 ASSERT_EQ(0, ret);
217
218 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
219 ASSERT_EQ(0, ret);
220 EXPECT_EQ(0, syscall(__NR_getpid)) {
221 TH_LOG("getpid() shouldn't ever return");
222 }
223 }
224
225 /* return code >= 0x80000000 is unused. */
TEST_SIGNAL(unknown_ret_is_kill_above_allow,SIGSYS)226 TEST_SIGNAL(unknown_ret_is_kill_above_allow, SIGSYS) {
227 struct sock_filter filter[] = {
228 BPF_STMT(BPF_RET+BPF_K, 0x90000000U),
229 };
230 struct sock_fprog prog = {
231 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
232 .filter = filter,
233 };
234
235 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
236 ASSERT_EQ(0, ret);
237
238 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
239 ASSERT_EQ(0, ret);
240 EXPECT_EQ(0, syscall(__NR_getpid)) {
241 TH_LOG("getpid() shouldn't ever return");
242 }
243 }
244
TEST_SIGNAL(KILL_all,SIGSYS)245 TEST_SIGNAL(KILL_all, SIGSYS) {
246 struct sock_filter filter[] = {
247 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
248 };
249 struct sock_fprog prog = {
250 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
251 .filter = filter,
252 };
253
254 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
255 ASSERT_EQ(0, ret);
256
257 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
258 ASSERT_EQ(0, ret);
259 }
260
TEST_SIGNAL(KILL_one,SIGSYS)261 TEST_SIGNAL(KILL_one, SIGSYS) {
262 struct sock_filter filter[] = {
263 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
264 offsetof(struct seccomp_data, nr)),
265 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 0, 1),
266 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
267 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
268 };
269 struct sock_fprog prog = {
270 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
271 .filter = filter,
272 };
273 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
274 pid_t parent = getppid();
275 ASSERT_EQ(0, ret);
276
277 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
278 ASSERT_EQ(0, ret);
279
280 EXPECT_EQ(parent, syscall(__NR_getppid));
281 /* getpid() should never return. */
282 EXPECT_EQ(0, syscall(__NR_getpid));
283 }
284
TEST_SIGNAL(KILL_one_arg_one,SIGSYS)285 TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
286 struct sock_filter filter[] = {
287 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
288 offsetof(struct seccomp_data, nr)),
289 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 1, 0),
290 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
291 /* Only both with lower 32-bit for now. */
292 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
293 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0C0FFEE, 0, 1),
294 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
295 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
296 };
297 struct sock_fprog prog = {
298 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
299 .filter = filter,
300 };
301 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
302 pid_t parent = getppid();
303 pid_t pid = getpid();
304 ASSERT_EQ(0, ret);
305
306 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
307 ASSERT_EQ(0, ret);
308
309 EXPECT_EQ(parent, syscall(__NR_getppid));
310 EXPECT_EQ(pid, syscall(__NR_getpid));
311 /* getpid() should never return. */
312 EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE));
313 }
314
TEST_SIGNAL(KILL_one_arg_six,SIGSYS)315 TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
316 struct sock_filter filter[] = {
317 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
318 offsetof(struct seccomp_data, nr)),
319 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 1, 0),
320 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
321 /* Only both with lower 32-bit for now. */
322 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(5)),
323 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0C0FFEE, 0, 1),
324 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
325 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
326 };
327 struct sock_fprog prog = {
328 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
329 .filter = filter,
330 };
331 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
332 pid_t parent = getppid();
333 pid_t pid = getpid();
334 ASSERT_EQ(0, ret);
335
336 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
337 ASSERT_EQ(0, ret);
338
339 EXPECT_EQ(parent, syscall(__NR_getppid));
340 EXPECT_EQ(pid, syscall(__NR_getpid));
341 /* getpid() should never return. */
342 EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE));
343 }
344
345 /* TODO(wad) add 64-bit versus 32-bit arg tests. */
346
TEST(arg_out_of_range)347 TEST(arg_out_of_range) {
348 struct sock_filter filter[] = {
349 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(6)),
350 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
351 };
352 struct sock_fprog prog = {
353 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
354 .filter = filter,
355 };
356 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
357 ASSERT_EQ(0, ret);
358
359 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
360 EXPECT_EQ(-1, ret);
361 EXPECT_EQ(EINVAL, errno);
362 }
363
TEST(ERRNO_one)364 TEST(ERRNO_one) {
365 struct sock_filter filter[] = {
366 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
367 offsetof(struct seccomp_data, nr)),
368 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 0, 1),
369 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | E2BIG),
370 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
371 };
372 struct sock_fprog prog = {
373 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
374 .filter = filter,
375 };
376 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
377 pid_t parent = getppid();
378 ASSERT_EQ(0, ret);
379
380 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
381 ASSERT_EQ(0, ret);
382
383 EXPECT_EQ(parent, syscall(__NR_getppid));
384 EXPECT_EQ(-1, read(0, NULL, 0));
385 EXPECT_EQ(E2BIG, errno);
386 }
387
TEST(ERRNO_one_ok)388 TEST(ERRNO_one_ok) {
389 struct sock_filter filter[] = {
390 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
391 offsetof(struct seccomp_data, nr)),
392 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 0, 1),
393 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | 0),
394 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
395 };
396 struct sock_fprog prog = {
397 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
398 .filter = filter,
399 };
400 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
401 pid_t parent = getppid();
402 ASSERT_EQ(0, ret);
403
404 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
405 ASSERT_EQ(0, ret);
406
407 EXPECT_EQ(parent, syscall(__NR_getppid));
408 /* "errno" of 0 is ok. */
409 EXPECT_EQ(0, read(0, NULL, 0));
410 }
411
FIXTURE_DATA(TRAP)412 FIXTURE_DATA(TRAP) {
413 struct sock_fprog prog;
414 };
415
FIXTURE_SETUP(TRAP)416 FIXTURE_SETUP(TRAP) {
417 struct sock_filter filter[] = {
418 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
419 offsetof(struct seccomp_data, nr)),
420 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 0, 1),
421 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
422 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
423 };
424 memset(&self->prog, 0, sizeof(self->prog));
425 self->prog.filter = malloc(sizeof(filter));
426 ASSERT_NE(NULL, self->prog.filter);
427 memcpy(self->prog.filter, filter, sizeof(filter));
428 self->prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
429 }
430
FIXTURE_TEARDOWN(TRAP)431 FIXTURE_TEARDOWN(TRAP) {
432 if (self->prog.filter)
433 free(self->prog.filter);
434 };
435
TEST_F_SIGNAL(TRAP,dfl,SIGSYS)436 TEST_F_SIGNAL(TRAP, dfl, SIGSYS) {
437 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
438 ASSERT_EQ(0, ret);
439
440 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
441 ASSERT_EQ(0, ret);
442 syscall(__NR_getpid);
443 }
444
445 /* Ensure that SIGSYS overrides SIG_IGN */
TEST_F_SIGNAL(TRAP,ign,SIGSYS)446 TEST_F_SIGNAL(TRAP, ign, SIGSYS) {
447 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
448 ASSERT_EQ(0, ret);
449
450 signal(SIGSYS, SIG_IGN);
451
452 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
453 ASSERT_EQ(0, ret);
454 syscall(__NR_getpid);
455 }
456
457 static struct siginfo TRAP_info;
458 static volatile int TRAP_nr;
TRAP_action(int nr,siginfo_t * info,void * void_context)459 static void TRAP_action(int nr, siginfo_t *info, void *void_context)
460 {
461 memcpy(&TRAP_info, info, sizeof(TRAP_info));
462 TRAP_nr = nr;
463 return;
464 }
465
TEST_F(TRAP,handler)466 TEST_F(TRAP, handler) {
467 int ret, test;
468 struct sigaction act;
469 sigset_t mask;
470 memset(&act, 0, sizeof(act));
471 sigemptyset(&mask);
472 sigaddset(&mask, SIGSYS);
473
474 act.sa_sigaction = &TRAP_action;
475 act.sa_flags = SA_SIGINFO;
476 ret = sigaction(SIGSYS, &act, NULL);
477 ASSERT_EQ(0, ret) {
478 TH_LOG("sigaction failed");
479 }
480 ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
481 ASSERT_EQ(0, ret) {
482 TH_LOG("sigprocmask failed");
483 }
484
485 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
486 ASSERT_EQ(0, ret);
487 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
488 ASSERT_EQ(0, ret);
489 TRAP_nr = 0;
490 memset(&TRAP_info, 0, sizeof(TRAP_info));
491 /* Expect the registers to be rolled back. (nr = error) may vary
492 * based on arch. */
493 ret = syscall(__NR_getpid);
494 /* Silence gcc warning about volatile. */
495 test = TRAP_nr;
496 EXPECT_EQ(SIGSYS, test);
497 struct local_sigsys {
498 void *_call_addr; /* calling user insn */
499 int _syscall; /* triggering system call number */
500 unsigned int _arch; /* AUDIT_ARCH_* of syscall */
501 } *sigsys = (struct local_sigsys *)
502 #ifdef si_syscall
503 &(TRAP_info.si_call_addr);
504 #else
505 &TRAP_info.si_pid;
506 #endif
507 EXPECT_EQ(__NR_getpid, sigsys->_syscall);
508 /* Make sure arch is non-zero. */
509 EXPECT_NE(0, sigsys->_arch);
510 EXPECT_NE(0, (unsigned long)sigsys->_call_addr);
511 }
512
FIXTURE_DATA(precedence)513 FIXTURE_DATA(precedence) {
514 struct sock_fprog allow;
515 struct sock_fprog trace;
516 struct sock_fprog error;
517 struct sock_fprog trap;
518 struct sock_fprog kill;
519 };
520
FIXTURE_SETUP(precedence)521 FIXTURE_SETUP(precedence) {
522 struct sock_filter allow_insns[] = {
523 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
524 };
525 struct sock_filter trace_insns[] = {
526 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
527 offsetof(struct seccomp_data, nr)),
528 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 1, 0),
529 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
530 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRACE),
531 };
532 struct sock_filter error_insns[] = {
533 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
534 offsetof(struct seccomp_data, nr)),
535 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 1, 0),
536 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
537 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO),
538 };
539 struct sock_filter trap_insns[] = {
540 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
541 offsetof(struct seccomp_data, nr)),
542 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 1, 0),
543 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
544 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
545 };
546 struct sock_filter kill_insns[] = {
547 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
548 offsetof(struct seccomp_data, nr)),
549 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 1, 0),
550 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
551 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
552 };
553 memset(self, 0, sizeof(*self));
554 #define FILTER_ALLOC(_x) \
555 self->_x.filter = malloc(sizeof(_x##_insns)); \
556 ASSERT_NE(NULL, self->_x.filter); \
557 memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \
558 self->_x.len = (unsigned short)(sizeof(_x##_insns)/sizeof(_x##_insns[0]))
559 FILTER_ALLOC(allow);
560 FILTER_ALLOC(trace);
561 FILTER_ALLOC(error);
562 FILTER_ALLOC(trap);
563 FILTER_ALLOC(kill);
564 }
565
FIXTURE_TEARDOWN(precedence)566 FIXTURE_TEARDOWN(precedence) {
567 #define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter)
568 FILTER_FREE(allow);
569 FILTER_FREE(trace);
570 FILTER_FREE(error);
571 FILTER_FREE(trap);
572 FILTER_FREE(kill);
573 }
574
TEST_F(precedence,allow_ok)575 TEST_F(precedence, allow_ok) {
576 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
577 pid_t parent = getppid();
578 pid_t res = 0;
579 ASSERT_EQ(0, ret);
580
581 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
582 ASSERT_EQ(0, ret);
583 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
584 ASSERT_EQ(0, ret);
585 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
586 ASSERT_EQ(0, ret);
587 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
588 ASSERT_EQ(0, ret);
589 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
590 ASSERT_EQ(0, ret);
591 /* Should work just fine. */
592 res = syscall(__NR_getppid);
593 EXPECT_EQ(parent, res);
594 }
595
TEST_F_SIGNAL(precedence,kill_is_highest,SIGSYS)596 TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS) {
597 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
598 pid_t parent = getppid();
599 pid_t res = 0;
600 ASSERT_EQ(0, ret);
601
602 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
603 ASSERT_EQ(0, ret);
604 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
605 ASSERT_EQ(0, ret);
606 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
607 ASSERT_EQ(0, ret);
608 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
609 ASSERT_EQ(0, ret);
610 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
611 ASSERT_EQ(0, ret);
612 /* Should work just fine. */
613 res = syscall(__NR_getppid);
614 EXPECT_EQ(parent, res);
615 /* getpid() should never return. */
616 res = syscall(__NR_getpid);
617 EXPECT_EQ(0, res);
618 }
619
TEST_F_SIGNAL(precedence,kill_is_highest_in_any_order,SIGSYS)620 TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS) {
621 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
622 pid_t parent = getppid();
623 ASSERT_EQ(0, ret);
624
625 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
626 ASSERT_EQ(0, ret);
627 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
628 ASSERT_EQ(0, ret);
629 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
630 ASSERT_EQ(0, ret);
631 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
632 ASSERT_EQ(0, ret);
633 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
634 ASSERT_EQ(0, ret);
635 /* Should work just fine. */
636 EXPECT_EQ(parent, syscall(__NR_getppid));
637 /* getpid() should never return. */
638 EXPECT_EQ(0, syscall(__NR_getpid));
639 }
640
TEST_F_SIGNAL(precedence,trap_is_second,SIGSYS)641 TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS) {
642 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
643 pid_t parent = getppid();
644 ASSERT_EQ(0, ret);
645
646 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
647 ASSERT_EQ(0, ret);
648 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
649 ASSERT_EQ(0, ret);
650 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
651 ASSERT_EQ(0, ret);
652 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
653 ASSERT_EQ(0, ret);
654 /* Should work just fine. */
655 EXPECT_EQ(parent, syscall(__NR_getppid));
656 /* getpid() should never return. */
657 EXPECT_EQ(0, syscall(__NR_getpid));
658 }
659
TEST_F_SIGNAL(precedence,trap_is_second_in_any_order,SIGSYS)660 TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS) {
661 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
662 pid_t parent = getppid();
663 ASSERT_EQ(0, ret);
664
665 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
666 ASSERT_EQ(0, ret);
667 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
668 ASSERT_EQ(0, ret);
669 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
670 ASSERT_EQ(0, ret);
671 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
672 ASSERT_EQ(0, ret);
673 /* Should work just fine. */
674 EXPECT_EQ(parent, syscall(__NR_getppid));
675 /* getpid() should never return. */
676 EXPECT_EQ(0, syscall(__NR_getpid));
677 }
678
TEST_F(precedence,errno_is_third)679 TEST_F(precedence, errno_is_third) {
680 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
681 pid_t parent = getppid();
682 ASSERT_EQ(0, ret);
683
684 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
685 ASSERT_EQ(0, ret);
686 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
687 ASSERT_EQ(0, ret);
688 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
689 ASSERT_EQ(0, ret);
690 /* Should work just fine. */
691 EXPECT_EQ(parent, syscall(__NR_getppid));
692 EXPECT_EQ(0, syscall(__NR_getpid));
693 }
694
TEST_F(precedence,errno_is_third_in_any_order)695 TEST_F(precedence, errno_is_third_in_any_order) {
696 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
697 pid_t parent = getppid();
698 ASSERT_EQ(0, ret);
699
700 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
701 ASSERT_EQ(0, ret);
702 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
703 ASSERT_EQ(0, ret);
704 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
705 ASSERT_EQ(0, ret);
706 /* Should work just fine. */
707 EXPECT_EQ(parent, syscall(__NR_getppid));
708 EXPECT_EQ(0, syscall(__NR_getpid));
709 }
710
TEST_F(precedence,trace_is_fourth)711 TEST_F(precedence, trace_is_fourth) {
712 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
713 pid_t parent = getppid();
714 ASSERT_EQ(0, ret);
715
716 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
717 ASSERT_EQ(0, ret);
718 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
719 ASSERT_EQ(0, ret);
720 /* Should work just fine. */
721 EXPECT_EQ(parent, syscall(__NR_getppid));
722 /* No ptracer */
723 EXPECT_EQ(-1, syscall(__NR_getpid));
724 }
725
TEST_F(precedence,trace_is_fourth_in_any_order)726 TEST_F(precedence, trace_is_fourth_in_any_order) {
727 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
728 pid_t parent = getppid();
729 ASSERT_EQ(0, ret);
730
731 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
732 ASSERT_EQ(0, ret);
733 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
734 ASSERT_EQ(0, ret);
735 /* Should work just fine. */
736 EXPECT_EQ(parent, syscall(__NR_getppid));
737 /* No ptracer */
738 EXPECT_EQ(-1, syscall(__NR_getpid));
739 }
740
741 #ifndef PTRACE_O_TRACESECCOMP
742 #define PTRACE_O_TRACESECCOMP 0x00000080
743 #endif
744
745 /* Catch the Ubuntu 12.04 value error. */
746 #if PTRACE_EVENT_SECCOMP != 7
747 #undef PTRACE_EVENT_SECCOMP
748 #endif
749
750 #ifndef PTRACE_EVENT_SECCOMP
751 #define PTRACE_EVENT_SECCOMP 7
752 #endif
753
754 #define IS_SECCOMP_EVENT(status) ((status >> 16) == PTRACE_EVENT_SECCOMP)
755 bool tracer_running;
tracer_stop(int sig)756 void tracer_stop(int sig)
757 {
758 tracer_running = false;
759 }
tracer(struct __test_metadata * _metadata,pid_t tracee,unsigned long poke_addr,int fd)760 void tracer(struct __test_metadata *_metadata, pid_t tracee,
761 unsigned long poke_addr, int fd) {
762 int ret = -1;
763 struct sigaction action = {
764 .sa_handler = tracer_stop,
765 };
766
767 /* Allow external shutdown. */
768 tracer_running = true;
769 ASSERT_EQ(0, sigaction(SIGUSR1, &action, NULL));
770
771 errno = 0;
772 while (ret == -1 && errno != EINVAL) {
773 ret = ptrace(PTRACE_ATTACH, tracee, NULL, 0);
774 }
775 ASSERT_EQ(0, ret) {
776 kill(tracee, SIGKILL);
777 }
778 /* Wait for attach stop */
779 wait(NULL);
780
781 ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, PTRACE_O_TRACESECCOMP);
782 ASSERT_EQ(0, ret) {
783 TH_LOG("Failed to set PTRACE_O_TRACESECCOMP");
784 kill(tracee, SIGKILL);
785 }
786 ptrace(PTRACE_CONT, tracee, NULL, 0);
787
788 /* Unblock the tracee */
789 ASSERT_EQ(1, write(fd, "A", 1));
790 ASSERT_EQ(0, close(fd));
791
792 /* Run until we're shut down. */
793 while (tracer_running) {
794 int status;
795 unsigned long msg;
796 if (wait(&status) != tracee)
797 continue;
798 if (WIFSIGNALED(status) || WIFEXITED(status))
799 /* Child is dead. Time to go. */
800 return;
801
802 /* Make sure this is a seccomp event. */
803 EXPECT_EQ(true, IS_SECCOMP_EVENT(status));
804
805 ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
806 EXPECT_EQ(0, ret);
807 /* If this fails, don't try to recover. */
808 ASSERT_EQ(0x1001, msg) {
809 kill(tracee, SIGKILL);
810 }
811 /*
812 * Poke in the message.
813 * Registers are not touched to try to keep this relatively arch
814 * agnostic.
815 */
816 ret = ptrace(PTRACE_POKEDATA, tracee, poke_addr, 0x1001);
817 EXPECT_EQ(0, ret);
818 ret = ptrace(PTRACE_CONT, tracee, NULL, NULL);
819 EXPECT_EQ(0, ret);
820 }
821 /* Directly report the status of our test harness results. */
822 syscall(__NR_exit, _metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
823 }
824
FIXTURE_DATA(TRACE)825 FIXTURE_DATA(TRACE) {
826 struct sock_fprog prog;
827 pid_t tracer;
828 long poked;
829 };
830
cont_handler(int num)831 void cont_handler(int num) {
832 }
833
FIXTURE_SETUP(TRACE)834 FIXTURE_SETUP(TRACE) {
835 struct sock_filter filter[] = {
836 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
837 offsetof(struct seccomp_data, nr)),
838 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 0, 1),
839 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRACE | 0x1001),
840 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
841 };
842 int pipefd[2];
843 char sync;
844 pid_t tracer_pid;
845 pid_t tracee = getpid();
846 unsigned long poke_addr = (unsigned long)&self->poked;
847 self->poked = 0;
848 memset(&self->prog, 0, sizeof(self->prog));
849 self->prog.filter = malloc(sizeof(filter));
850 ASSERT_NE(NULL, self->prog.filter);
851 memcpy(self->prog.filter, filter, sizeof(filter));
852 self->prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
853
854 /* Setup a pipe for clean synchronization. */
855 ASSERT_EQ(0, pipe(pipefd));
856
857 /* Fork a child which we'll promote to tracer */
858 tracer_pid = fork();
859 ASSERT_LE(0, tracer_pid);
860 signal(SIGALRM, cont_handler);
861 if (tracer_pid == 0) {
862 close(pipefd[0]);
863 tracer(_metadata, tracee, poke_addr, pipefd[1]);
864 syscall(__NR_exit, 0);
865 }
866 close(pipefd[1]);
867 self->tracer = tracer_pid;
868 prctl(PR_SET_PTRACER, self->tracer, 0, 0, 0);
869 long ret = read(pipefd[0], &sync, 1);
870 close(pipefd[0]);
871 }
872
FIXTURE_TEARDOWN(TRACE)873 FIXTURE_TEARDOWN(TRACE) {
874 if (self->tracer) {
875 int status;
876 /*
877 * Extract the exit code from the other process and
878 * adopt it for ourselves in case its asserts failed.
879 */
880 ASSERT_EQ(0, kill(self->tracer, SIGUSR1));
881 ASSERT_EQ(self->tracer, waitpid(self->tracer, &status, 0));
882 if (WEXITSTATUS(status))
883 _metadata->passed = 0;
884 }
885 if (self->prog.filter)
886 free(self->prog.filter);
887 };
888
TEST_F(TRACE,read_has_side_effects)889 TEST_F(TRACE, read_has_side_effects) {
890 ssize_t ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
891 ASSERT_EQ(0, ret);
892
893 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
894 ASSERT_EQ(0, ret);
895
896 EXPECT_EQ(0, self->poked);
897 ret = read(-1, NULL, 0);
898 EXPECT_EQ(-1, ret);
899 EXPECT_EQ(0x1001, self->poked);
900 }
901
TEST_F(TRACE,getpid_runs_normally)902 TEST_F(TRACE, getpid_runs_normally) {
903 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
904 ASSERT_EQ(0, ret);
905
906 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
907 ASSERT_EQ(0, ret);
908
909 EXPECT_EQ(0, self->poked);
910 EXPECT_NE(0, syscall(__NR_getpid));
911 EXPECT_EQ(0, self->poked);
912 }
913
914 #ifndef __NR_seccomp
915 # if defined(__i386__)
916 # define __NR_seccomp 354
917 # elif defined(__x86_64__)
918 # define __NR_seccomp 317
919 # else
920 # define __NR_seccomp 0xffff
921 # endif
922 #endif
923
924 #ifndef SECCOMP_SET_MODE_STRICT
925 #define SECCOMP_SET_MODE_STRICT 0
926 #endif
927
928 #ifndef SECCOMP_SET_MODE_FILTER
929 #define SECCOMP_SET_MODE_FILTER 1
930 #endif
931
932 #ifndef SECCOMP_FLAG_FILTER_TSYNC
933 #define SECCOMP_FLAG_FILTER_TSYNC 1
934 #endif
935
936 #ifndef seccomp
seccomp(unsigned int op,unsigned int flags,struct sock_fprog * filter)937 int seccomp(unsigned int op, unsigned int flags, struct sock_fprog *filter)
938 {
939 errno = 0;
940 return syscall(__NR_seccomp, op, flags, filter);
941 }
942 #endif
943
944 /* The following tests are commented out because they test
945 * features that are currently unsupported.
946 */
947 #if 0
948
949 TEST(seccomp_syscall) {
950 struct sock_filter filter[] = {
951 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
952 };
953 struct sock_fprog prog = {
954 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
955 .filter = filter,
956 };
957 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
958 ASSERT_EQ(0, ret) {
959 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
960 }
961
962 /* Reject insane operation. */
963 ret = seccomp(-1, 0, &prog);
964 EXPECT_EQ(EINVAL, errno) {
965 TH_LOG("Did not reject crazy op value!");
966 }
967
968 /* Reject strict with flags or pointer. */
969 ret = seccomp(SECCOMP_SET_MODE_STRICT, -1, NULL);
970 EXPECT_EQ(EINVAL, errno) {
971 TH_LOG("Did not reject mode strict with flags!");
972 }
973 ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, &prog);
974 EXPECT_EQ(EINVAL, errno) {
975 TH_LOG("Did not reject mode strict with uargs!");
976 }
977
978 /* Reject insane args for filter. */
979 ret = seccomp(SECCOMP_SET_MODE_FILTER, -1, &prog);
980 EXPECT_EQ(EINVAL, errno) {
981 TH_LOG("Did not reject crazy filter flags!");
982 }
983 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, NULL);
984 EXPECT_EQ(EFAULT, errno) {
985 TH_LOG("Did not reject NULL filter!");
986 }
987
988 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
989 EXPECT_EQ(0, errno) {
990 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER: %s",
991 strerror(errno));
992 }
993 }
994
995 TEST(seccomp_syscall_mode_lock) {
996 struct sock_filter filter[] = {
997 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
998 };
999 struct sock_fprog prog = {
1000 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
1001 .filter = filter,
1002 };
1003 long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
1004 ASSERT_EQ(0, ret) {
1005 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1006 }
1007
1008 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
1009 EXPECT_EQ(0, ret) {
1010 TH_LOG("Could not install filter!");
1011 }
1012
1013 /* Make sure neither entry point will switch to strict. */
1014 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, 0, 0, 0);
1015 EXPECT_EQ(EINVAL, errno) {
1016 TH_LOG("Switched to mode strict!");
1017 }
1018
1019 ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, NULL);
1020 EXPECT_EQ(EINVAL, errno) {
1021 TH_LOG("Switched to mode strict!");
1022 }
1023 }
1024
1025 #define TSYNC_SIBLINGS 2
1026 struct tsync_sibling {
1027 pthread_t tid;
1028 pid_t system_tid;
1029 sem_t *started;
1030 pthread_cond_t *cond;
1031 pthread_mutex_t *mutex;
1032 int diverge;
1033 int num_waits;
1034 struct sock_fprog *prog;
1035 struct __test_metadata *metadata;
1036 };
1037
1038 FIXTURE_DATA(TSYNC) {
1039 struct sock_fprog root_prog, apply_prog;
1040 struct tsync_sibling sibling[TSYNC_SIBLINGS];
1041 sem_t started;
1042 pthread_cond_t cond;
1043 pthread_mutex_t mutex;
1044 int sibling_count;
1045 };
1046
1047 FIXTURE_SETUP(TSYNC) {
1048 struct sock_filter root_filter[] = {
1049 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
1050 };
1051 struct sock_filter apply_filter[] = {
1052 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
1053 offsetof(struct seccomp_data, nr)),
1054 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 0, 1),
1055 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
1056 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
1057 };
1058 memset(&self->root_prog, 0, sizeof(self->root_prog));
1059 memset(&self->apply_prog, 0, sizeof(self->apply_prog));
1060 memset(&self->sibling, 0, sizeof(self->sibling));
1061 self->root_prog.filter = malloc(sizeof(root_filter));
1062 ASSERT_NE(NULL, self->root_prog.filter);
1063 memcpy(self->root_prog.filter, &root_filter, sizeof(root_filter));
1064 self->root_prog.len = (unsigned short)(sizeof(root_filter)/sizeof(root_filter[0]));
1065
1066 self->apply_prog.filter = malloc(sizeof(apply_filter));
1067 ASSERT_NE(NULL, self->apply_prog.filter);
1068 memcpy(self->apply_prog.filter, &apply_filter, sizeof(apply_filter));
1069 self->apply_prog.len = (unsigned short)(sizeof(apply_filter)/sizeof(apply_filter[0]));
1070
1071 self->sibling_count = 0;
1072 pthread_mutex_init(&self->mutex, NULL);
1073 pthread_cond_init(&self->cond, NULL);
1074 sem_init(&self->started, 0, 0);
1075 self->sibling[0].tid = 0;
1076 self->sibling[0].cond = &self->cond;
1077 self->sibling[0].started = &self->started;
1078 self->sibling[0].mutex = &self->mutex;
1079 self->sibling[0].diverge = 0;
1080 self->sibling[0].num_waits = 1;
1081 self->sibling[0].prog = &self->root_prog;
1082 self->sibling[0].metadata = _metadata;
1083 self->sibling[1].tid = 0;
1084 self->sibling[1].cond = &self->cond;
1085 self->sibling[1].started = &self->started;
1086 self->sibling[1].mutex = &self->mutex;
1087 self->sibling[1].diverge = 0;
1088 self->sibling[1].prog = &self->root_prog;
1089 self->sibling[1].num_waits = 1;
1090 self->sibling[1].metadata = _metadata;
1091
1092 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
1093 TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
1094 }
1095 }
1096
1097 FIXTURE_TEARDOWN(TSYNC) {
1098 int sib = 0;
1099 if (self->root_prog.filter)
1100 free(self->root_prog.filter);
1101 if (self->apply_prog.filter)
1102 free(self->apply_prog.filter);
1103
1104 for ( ; sib < self->sibling_count; ++sib) {
1105 struct tsync_sibling *s = &self->sibling[sib];
1106 void *status;
1107 if (!s->tid)
1108 continue;
1109 if (pthread_kill(s->tid, 0)) {
1110 pthread_cancel(s->tid);
1111 pthread_join(s->tid, &status);
1112 }
1113 }
1114 pthread_mutex_destroy(&self->mutex);
1115 pthread_cond_destroy(&self->cond);
1116 sem_destroy(&self->started);
1117 };
1118
1119 void *tsync_sibling(void *data)
1120 {
1121 long ret = 0;
1122 struct tsync_sibling *me = data;
1123 struct __test_metadata *_metadata = me->metadata; /* enable TH_LOG */
1124 me->system_tid = syscall(__NR_gettid);
1125
1126 pthread_mutex_lock(me->mutex);
1127 if (me->diverge) {
1128 /* Just re-apply the root prog to fork the tree */
1129 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER,
1130 me->prog, 0, 0);
1131 }
1132 sem_post(me->started);
1133 /* Return outside of started so parent notices failures. */
1134 if (ret) {
1135 pthread_mutex_unlock(me->mutex);
1136 return (void *)SIBLING_EXIT_FAILURE;
1137 }
1138 do {
1139 pthread_cond_wait(me->cond, me->mutex);
1140 me->num_waits = me->num_waits - 1;
1141 }
1142 while (me->num_waits);
1143 pthread_mutex_unlock(me->mutex);
1144 ret = read(0, NULL, 0);
1145 return (void *)SIBLING_EXIT_UNKILLED;
1146 }
1147
1148 void tsync_start_sibling(struct tsync_sibling *sibling)
1149 {
1150 pthread_create(&sibling->tid, NULL, tsync_sibling, (void *)sibling);
1151 }
1152
1153 TEST_F(TSYNC, siblings_fail_prctl) {
1154 long ret, sib;
1155 void *status;
1156 struct sock_filter filter[] = {
1157 BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
1158 offsetof(struct seccomp_data, nr)),
1159 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_prctl, 0, 1),
1160 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | EINVAL),
1161 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
1162 };
1163 struct sock_fprog prog = {
1164 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
1165 .filter = filter,
1166 };
1167
1168 /* Check prctl failure detection by requesting sib 0 diverge. */
1169 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
1170
1171 self->sibling[0].diverge = 1;
1172 tsync_start_sibling(&self->sibling[0]);
1173 tsync_start_sibling(&self->sibling[1]);
1174
1175 while (self->sibling_count < TSYNC_SIBLINGS) {
1176 sem_wait(&self->started);
1177 self->sibling_count++;
1178 }
1179
1180 /* Signal the threads to clean up*/
1181 pthread_mutex_lock(&self->mutex);
1182 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1183 TH_LOG("cond broadcast non-zero");
1184 }
1185 pthread_mutex_unlock(&self->mutex);
1186
1187 /* Ensure diverging sibling failed to call prctl. */
1188 pthread_join(self->sibling[0].tid, &status);
1189 EXPECT_EQ(SIBLING_EXIT_FAILURE, (long)status);
1190 pthread_join(self->sibling[1].tid, &status);
1191 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1192 }
1193
1194 TEST_F(TSYNC, two_siblings_with_ancestor) {
1195 long ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
1196 void *status;
1197 ASSERT_EQ(0, ret) {
1198 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
1199 }
1200 tsync_start_sibling(&self->sibling[0]);
1201 tsync_start_sibling(&self->sibling[1]);
1202
1203 while (self->sibling_count < TSYNC_SIBLINGS) {
1204 sem_wait(&self->started);
1205 self->sibling_count++;
1206 }
1207
1208 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1209 &self->apply_prog);
1210 ASSERT_EQ(0, ret) {
1211 TH_LOG("Could install filter on all threads!");
1212 }
1213 /* Tell the siblings to test the policy */
1214 pthread_mutex_lock(&self->mutex);
1215 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1216 TH_LOG("cond broadcast non-zero");
1217 }
1218 pthread_mutex_unlock(&self->mutex);
1219 /* Ensure they are both killed and don't exit cleanly. */
1220 pthread_join(self->sibling[0].tid, &status);
1221 EXPECT_EQ(0x0, (long)status);
1222 pthread_join(self->sibling[1].tid, &status);
1223 EXPECT_EQ(0x0, (long)status);
1224 }
1225
1226 TEST_F(TSYNC, two_siblings_with_one_divergence) {
1227 long ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
1228 void *status;
1229 ASSERT_EQ(0, ret) {
1230 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
1231 }
1232 self->sibling[0].diverge = 1;
1233 tsync_start_sibling(&self->sibling[0]);
1234 tsync_start_sibling(&self->sibling[1]);
1235
1236 while (self->sibling_count < TSYNC_SIBLINGS) {
1237 sem_wait(&self->started);
1238 self->sibling_count++;
1239 }
1240
1241 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1242 &self->apply_prog);
1243 ASSERT_EQ(self->sibling[0].system_tid, ret) {
1244 TH_LOG("Did not fail on diverged sibling.");
1245 }
1246
1247 /* Wake the threads */
1248 pthread_mutex_lock(&self->mutex);
1249 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1250 TH_LOG("cond broadcast non-zero");
1251 }
1252 pthread_mutex_unlock(&self->mutex);
1253
1254 /* Ensure they are both unkilled. */
1255 pthread_join(self->sibling[0].tid, &status);
1256 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1257 pthread_join(self->sibling[1].tid, &status);
1258 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1259 }
1260
1261 TEST_F(TSYNC, two_siblings_not_under_filter) {
1262 long ret, sib;
1263 void *status;
1264 /*
1265 * Sibling 0 will have its own seccomp policy
1266 * and Sibling 1 will not be under seccomp at
1267 * all. Sibling 1 will enter seccomp and 0
1268 * will cause failure.
1269 */
1270 self->sibling[0].diverge = 1;
1271 tsync_start_sibling(&self->sibling[0]);
1272 tsync_start_sibling(&self->sibling[1]);
1273
1274 while (self->sibling_count < TSYNC_SIBLINGS) {
1275 sem_wait(&self->started);
1276 self->sibling_count++;
1277 }
1278
1279 ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
1280 ASSERT_EQ(0, ret) {
1281 TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
1282 }
1283
1284 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1285 &self->apply_prog);
1286 ASSERT_EQ(ret, self->sibling[0].system_tid) {
1287 TH_LOG("Did not fail on diverged sibling.");
1288 }
1289 sib = 1;
1290 if (ret == self->sibling[0].system_tid)
1291 sib = 0;
1292
1293 pthread_mutex_lock(&self->mutex);
1294
1295 /* Increment the other siblings num_waits so we can clean up
1296 * the one we just saw.
1297 */
1298 self->sibling[!sib].num_waits += 1;
1299
1300 /* Signal the thread to clean up*/
1301 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1302 TH_LOG("cond broadcast non-zero");
1303 }
1304 pthread_mutex_unlock(&self->mutex);
1305 pthread_join(self->sibling[sib].tid, &status);
1306 EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
1307 /* Poll for actual task death. pthread_join doesn't guarantee it. */
1308 while (!kill(self->sibling[sib].system_tid, 0)) sleep(0.1);
1309 /* Switch to the remaining sibling */
1310 sib = !sib;
1311
1312 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1313 &self->apply_prog);
1314 ASSERT_EQ(0, ret) {
1315 TH_LOG("Expected the remaining sibling to sync");
1316 };
1317
1318 pthread_mutex_lock(&self->mutex);
1319
1320 /* If remaining sibling didn't have a chance to wake up during
1321 * the first broadcast, manually reduce the num_waits now.
1322 */
1323 if (self->sibling[sib].num_waits > 1)
1324 self->sibling[sib].num_waits = 1;
1325 ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
1326 TH_LOG("cond broadcast non-zero");
1327 }
1328 pthread_mutex_unlock(&self->mutex);
1329 pthread_join(self->sibling[sib].tid, &status);
1330 EXPECT_EQ(0, (long)status);
1331 /* Poll for actual task death. pthread_join doesn't guarantee it. */
1332 while (!kill(self->sibling[sib].system_tid, 0)) sleep(0.1);
1333
1334 ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
1335 &self->apply_prog);
1336 ASSERT_EQ(0, ret); /* just us chickens */
1337 }
1338
1339 #endif
1340
1341 /*
1342 * TODO:
1343 * - add microbenchmarks
1344 * - expand NNP testing
1345 * - better arch-specific TRACE and TRAP handlers.
1346 * - endianness checking when appropriate
1347 * - 64-bit arg prodding
1348 * - arch value testing (x86 modes especially)
1349 * - ...
1350 */
1351
1352 TEST_HARNESS_MAIN
1353