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 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 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 */ 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. */ 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 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 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 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 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 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. */ 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 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 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 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 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 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 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 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 412 FIXTURE_DATA(TRAP) { 413 struct sock_fprog prog; 414 }; 415 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 431 FIXTURE_TEARDOWN(TRAP) { 432 if (self->prog.filter) 433 free(self->prog.filter); 434 }; 435 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 */ 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; 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 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 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 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 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 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 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 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 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 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 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 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 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 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; 756 void tracer_stop(int sig) 757 { 758 tracer_running = false; 759 } 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 825 FIXTURE_DATA(TRACE) { 826 struct sock_fprog prog; 827 pid_t tracer; 828 long poked; 829 }; 830 831 void cont_handler(int num) { 832 } 833 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 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 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 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 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