1 /* Copyright 2016 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 * 5 * Test syscall filtering using gtest. 6 */ 7 8 #include <asm/unistd.h> 9 #include <errno.h> 10 #include <fcntl.h> /* For O_WRONLY. */ 11 12 #include <gtest/gtest.h> 13 #include <string> 14 15 #include "bpf.h" 16 #include "syscall_filter.h" 17 #include "syscall_filter_unittest_macros.h" 18 #include "util.h" 19 20 namespace { 21 22 // TODO(jorgelo): Android unit tests don't currently support data files. 23 // Re-enable by creating a temporary policy file at runtime. 24 #if !defined(__ANDROID__) 25 26 std::string source_path(std::string file) { 27 std::string srcdir = getenv("SRC") ? : "."; 28 return srcdir + "/" + file; 29 } 30 31 #endif 32 33 // Simple C++ -> C wrappers to simplify test code. 34 35 enum ret_trap { 36 USE_RET_KILL = 0, 37 USE_RET_TRAP = 1, 38 }; 39 40 enum use_logging { 41 NO_LOGGING = 0, 42 USE_LOGGING = 1, 43 }; 44 45 int test_compile_filter( 46 std::string filename, 47 FILE* policy_file, 48 struct sock_fprog* prog, 49 enum ret_trap do_ret_trap = USE_RET_KILL, 50 enum use_logging add_logging_syscalls = NO_LOGGING) { 51 return compile_filter(filename.c_str(), policy_file, prog, do_ret_trap, 52 add_logging_syscalls); 53 } 54 55 int test_compile_file( 56 std::string filename, 57 FILE* policy_file, 58 struct filter_block* head, 59 struct filter_block** arg_blocks, 60 struct bpf_labels* labels, 61 enum ret_trap use_ret_trap = USE_RET_KILL, 62 enum use_logging allow_logging = NO_LOGGING, 63 unsigned int include_level = 0) { 64 return compile_file(filename.c_str(), policy_file, head, arg_blocks, labels, 65 use_ret_trap, allow_logging, include_level); 66 } 67 68 struct filter_block* test_compile_policy_line( 69 struct parser_state* state, 70 int nr, 71 std::string policy_line, 72 unsigned int label_id, 73 struct bpf_labels* labels, 74 enum ret_trap do_ret_trap = USE_RET_KILL) { 75 return compile_policy_line(state, nr, policy_line.c_str(), label_id, labels, 76 do_ret_trap); 77 } 78 79 } // namespace 80 81 TEST(util, parse_constant_unsigned) { 82 char *end; 83 long int c = 0; 84 std::string constant; 85 86 #if defined(BITS32) 87 constant = "0x80000000"; 88 c = parse_constant(const_cast<char*>(constant.data()), &end); 89 EXPECT_EQ(0x80000000U, static_cast<unsigned long int>(c)); 90 91 #elif defined(BITS64) 92 constant = "0x8000000000000000"; 93 c = parse_constant(const_cast<char*>(constant.data()), &end); 94 EXPECT_EQ(0x8000000000000000UL, static_cast<unsigned long int>(c)); 95 #endif 96 } 97 98 TEST(util, parse_constant_unsigned_toobig) { 99 char *end; 100 long int c = 0; 101 std::string constant; 102 103 #if defined(BITS32) 104 constant = "0x100000000"; // Too big for 32-bit unsigned long int. 105 c = parse_constant(const_cast<char*>(constant.data()), &end); 106 // Error case should return 0. 107 EXPECT_EQ(0, c); 108 109 #elif defined(BITS64) 110 constant = "0x10000000000000000"; 111 c = parse_constant(const_cast<char*>(constant.data()), &end); 112 // Error case should return 0. 113 EXPECT_EQ(0, c); 114 #endif 115 } 116 117 TEST(util, parse_constant_signed) { 118 char *end; 119 long int c = 0; 120 std::string constant = "-1"; 121 c = parse_constant(const_cast<char*>(constant.data()), &end); 122 EXPECT_EQ(-1, c); 123 } 124 125 TEST(util, parse_constant_signed_toonegative) { 126 char *end; 127 long int c = 0; 128 std::string constant; 129 130 #if defined(BITS32) 131 constant = "-0x80000001"; 132 c = parse_constant(const_cast<char*>(constant.data()), &end); 133 // Error case should return 0. 134 EXPECT_EQ(0, c); 135 136 #elif defined(BITS64) 137 constant = "-0x8000000000000001"; 138 c = parse_constant(const_cast<char*>(constant.data()), &end); 139 // Error case should return 0. 140 EXPECT_EQ(0, c); 141 #endif 142 } 143 144 TEST(util, parse_constant_complements) { 145 char* end; 146 long int c = 0; 147 std::string constant; 148 149 #if defined(BITS32) 150 constant = "~0x005AF0FF|~0xFFA50FFF"; 151 c = parse_constant(const_cast<char*>(constant.data()), &end); 152 EXPECT_EQ(c, 0xFFFFFF00); 153 constant = "0x0F|~(0x005AF000|0x00A50FFF)|0xF0"; 154 c = parse_constant(const_cast<char*>(constant.data()), &end); 155 EXPECT_EQ(c, 0xFF0000FF); 156 157 #elif defined(BITS64) 158 constant = "~0x00005A5AF0F0FFFF|~0xFFFFA5A50F0FFFFF"; 159 c = parse_constant(const_cast<char*>(constant.data()), &end); 160 EXPECT_EQ(c, 0xFFFFFFFFFFFF0000UL); 161 constant = "0x00FF|~(0x00005A5AF0F00000|0x0000A5A50F0FFFFF)|0xFF00"; 162 c = parse_constant(const_cast<char*>(constant.data()), &end); 163 EXPECT_EQ(c, 0xFFFF00000000FFFFUL); 164 #endif 165 } 166 167 TEST(util, parse_parenthesized_expresions) { 168 char* end; 169 170 const std::vector<const char*> bad_expressions = { 171 "(1", "1)", "(1)1", "|(1)", "(1)|", "()", 172 "(", "((", "(()", "(()1", "1(0)", 173 }; 174 for (const auto* expression : bad_expressions) { 175 std::string mutable_expression = expression; 176 long int c = 177 parse_constant(const_cast<char*>(mutable_expression.data()), &end); 178 EXPECT_EQ(reinterpret_cast<const void*>(end), 179 reinterpret_cast<const void*>(mutable_expression.data())); 180 // Error case should return 0. 181 EXPECT_EQ(c, 0) << "For expression: \"" << expression << "\""; 182 } 183 184 const std::vector<const char*> good_expressions = { 185 "(3)", "(1)|2", "1|(2)", "(1)|(2)", "((3))", "0|(1|2)", "(0|1|2)", 186 }; 187 for (const auto* expression : good_expressions) { 188 std::string mutable_expression = expression; 189 long int c = 190 parse_constant(const_cast<char*>(mutable_expression.data()), &end); 191 EXPECT_EQ(c, 3) << "For expression: \"" << expression << "\""; 192 } 193 } 194 195 /* Test that setting one BPF instruction works. */ 196 TEST(bpf, set_bpf_instr) { 197 struct sock_filter instr; 198 unsigned char code = BPF_LD + BPF_W + BPF_ABS; 199 unsigned int k = 4; 200 unsigned char jt = 1, jf = 2; 201 202 size_t len = set_bpf_instr(&instr, code, k, jt, jf); 203 204 EXPECT_EQ(len, 1U); 205 EXPECT_EQ_BLOCK(&instr, code, k, jt, jf); 206 } 207 208 TEST(bpf, bpf_load_arg) { 209 struct sock_filter load_arg[BPF_LOAD_ARG_LEN]; 210 const int argidx = 1; 211 size_t len = bpf_load_arg(load_arg, argidx); 212 213 EXPECT_EQ(len, BPF_LOAD_ARG_LEN); 214 215 #if defined(BITS32) 216 EXPECT_EQ_STMT(&load_arg[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx)); 217 #elif defined(BITS64) 218 EXPECT_EQ_STMT(&load_arg[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx)); 219 EXPECT_EQ_STMT(&load_arg[1], BPF_ST, 0); 220 EXPECT_EQ_STMT(&load_arg[2], BPF_LD + BPF_W + BPF_ABS, HI_ARG(argidx)); 221 EXPECT_EQ_STMT(&load_arg[3], BPF_ST, 1); 222 #endif 223 } 224 225 TEST(bpf, bpf_comp_jeq) { 226 struct sock_filter comp_jeq[BPF_COMP_LEN]; 227 unsigned long c = 1; 228 unsigned char jt = 1; 229 unsigned char jf = 2; 230 231 size_t len = bpf_comp_jeq(comp_jeq, c, jt, jf); 232 233 EXPECT_EQ(len, BPF_COMP_LEN); 234 235 #if defined(BITS32) 236 EXPECT_EQ_BLOCK(&comp_jeq[0], BPF_JMP + BPF_JEQ + BPF_K, c, jt, jf); 237 #elif defined(BITS64) 238 EXPECT_EQ_BLOCK(&comp_jeq[0], BPF_JMP + BPF_JEQ + BPF_K, 0, 0, jf + 2); 239 EXPECT_EQ_STMT(&comp_jeq[1], BPF_LD + BPF_MEM, 0); 240 EXPECT_EQ_BLOCK(&comp_jeq[2], BPF_JMP + BPF_JEQ + BPF_K, c, jt, jf); 241 #endif 242 } 243 244 TEST(bpf, bpf_comp_jset) { 245 struct sock_filter comp_jset[BPF_COMP_LEN]; 246 unsigned long mask = (1UL << (sizeof(unsigned long) * 8 - 1)) | O_WRONLY; 247 unsigned char jt = 1; 248 unsigned char jf = 2; 249 250 size_t len = bpf_comp_jset(comp_jset, mask, jt, jf); 251 252 EXPECT_EQ(len, BPF_COMP_LEN); 253 254 #if defined(BITS32) 255 EXPECT_EQ_BLOCK(&comp_jset[0], BPF_JMP + BPF_JSET + BPF_K, mask, jt, jf); 256 #elif defined(BITS64) 257 EXPECT_EQ_BLOCK( 258 &comp_jset[0], BPF_JMP + BPF_JSET + BPF_K, 0x80000000, jt + 2, 0); 259 EXPECT_EQ_STMT(&comp_jset[1], BPF_LD + BPF_MEM, 0); 260 EXPECT_EQ_BLOCK(&comp_jset[2], BPF_JMP + BPF_JSET + BPF_K, O_WRONLY, jt, jf); 261 #endif 262 } 263 264 TEST(bpf, bpf_comp_jin) { 265 struct sock_filter comp_jin[BPF_COMP_LEN]; 266 unsigned long mask = (1UL << (sizeof(unsigned long) * 8 - 1)) | O_WRONLY; 267 unsigned char jt = 10; 268 unsigned char jf = 20; 269 270 size_t len = bpf_comp_jin(comp_jin, mask, jt, jf); 271 272 EXPECT_EQ(len, BPF_COMP_LEN); 273 274 #if defined(BITS32) 275 EXPECT_EQ_BLOCK(&comp_jin[0], BPF_JMP + BPF_JSET + BPF_K, ~mask, jf, jt); 276 #elif defined(BITS64) 277 EXPECT_EQ_BLOCK( 278 &comp_jin[0], BPF_JMP + BPF_JSET + BPF_K, 0x7FFFFFFF, jf + 2, 0); 279 EXPECT_EQ_STMT(&comp_jin[1], BPF_LD + BPF_MEM, 0); 280 EXPECT_EQ_BLOCK(&comp_jin[2], BPF_JMP + BPF_JSET + BPF_K, ~O_WRONLY, jf, jt); 281 #endif 282 } 283 284 TEST(bpf, bpf_arg_comp) { 285 struct sock_filter *arg_comp; 286 int op = EQ; 287 const int argidx = 1; 288 unsigned long c = 3; 289 unsigned int label_id = 0; 290 291 size_t len = bpf_arg_comp(&arg_comp, op, argidx, c, label_id); 292 293 EXPECT_EQ(len, BPF_ARG_COMP_LEN + 1); 294 295 #if defined(BITS32) 296 EXPECT_EQ_STMT(&arg_comp[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx)); 297 EXPECT_EQ_BLOCK(&arg_comp[1], BPF_JMP + BPF_JEQ + BPF_K, c, 1, 0); 298 EXPECT_JUMP_LBL(&arg_comp[2]); 299 #elif defined(BITS64) 300 EXPECT_EQ_STMT(&arg_comp[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx)); 301 EXPECT_EQ_STMT(&arg_comp[1], BPF_ST, 0); 302 EXPECT_EQ_STMT(&arg_comp[2], BPF_LD + BPF_W + BPF_ABS, HI_ARG(argidx)); 303 EXPECT_EQ_STMT(&arg_comp[3], BPF_ST, 1); 304 305 EXPECT_EQ_BLOCK(&arg_comp[4], BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 2); 306 EXPECT_EQ_STMT(&arg_comp[5], BPF_LD + BPF_MEM, 0); 307 EXPECT_EQ_BLOCK(&arg_comp[6], BPF_JMP + BPF_JEQ + BPF_K, c, 1, 0); 308 EXPECT_JUMP_LBL(&arg_comp[7]); 309 #endif 310 free(arg_comp); 311 } 312 313 TEST(bpf, bpf_validate_arch) { 314 struct sock_filter validate_arch[ARCH_VALIDATION_LEN]; 315 316 size_t len = bpf_validate_arch(validate_arch); 317 318 EXPECT_EQ(len, ARCH_VALIDATION_LEN); 319 EXPECT_ARCH_VALIDATION(validate_arch); 320 } 321 322 TEST(bpf, bpf_allow_syscall) { 323 struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN]; 324 int nr = 1; 325 326 size_t len = bpf_allow_syscall(allow_syscall, nr); 327 328 EXPECT_EQ(len, ALLOW_SYSCALL_LEN); 329 EXPECT_ALLOW_SYSCALL(allow_syscall, nr); 330 } 331 332 TEST(bpf, bpf_allow_syscall_args) { 333 struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN]; 334 int nr = 1; 335 unsigned int id = 1024; 336 337 size_t len = bpf_allow_syscall_args(allow_syscall, nr, id); 338 339 EXPECT_EQ(len, ALLOW_SYSCALL_LEN); 340 EXPECT_ALLOW_SYSCALL_ARGS(allow_syscall, nr, id, JUMP_JT, JUMP_JF); 341 } 342 343 class BpfLabelTest : public ::testing::Test { 344 protected: 345 virtual void SetUp() { labels_.count = 0; } 346 virtual void TearDown() { free_label_strings(&labels_); } 347 struct bpf_labels labels_; 348 }; 349 350 TEST_F(BpfLabelTest, zero_length_filter) { 351 int res = bpf_resolve_jumps(&labels_, nullptr, 0); 352 353 EXPECT_EQ(res, 0); 354 EXPECT_EQ(labels_.count, 0U); 355 } 356 357 TEST_F(BpfLabelTest, single_label) { 358 struct sock_filter test_label[1]; 359 360 int id = bpf_label_id(&labels_, "test"); 361 set_bpf_lbl(test_label, id); 362 int res = bpf_resolve_jumps(&labels_, test_label, 1); 363 364 EXPECT_EQ(res, 0); 365 EXPECT_EQ(labels_.count, 1U); 366 } 367 368 TEST_F(BpfLabelTest, repeated_label) { 369 struct sock_filter test_label[2]; 370 371 int id = bpf_label_id(&labels_, "test"); 372 set_bpf_lbl(&test_label[0], id); 373 set_bpf_lbl(&test_label[1], id); 374 int res = bpf_resolve_jumps(&labels_, test_label, 2); 375 376 EXPECT_EQ(res, -1); 377 } 378 379 TEST_F(BpfLabelTest, jump_with_no_label) { 380 struct sock_filter test_jump[1]; 381 382 set_bpf_jump_lbl(test_jump, 14831); 383 int res = bpf_resolve_jumps(&labels_, test_jump, 1); 384 385 EXPECT_EQ(res, -1); 386 } 387 388 TEST_F(BpfLabelTest, jump_to_valid_label) { 389 struct sock_filter test_jump[2]; 390 391 int id = bpf_label_id(&labels_, "test"); 392 set_bpf_jump_lbl(&test_jump[0], id); 393 set_bpf_lbl(&test_jump[1], id); 394 395 int res = bpf_resolve_jumps(&labels_, test_jump, 2); 396 EXPECT_EQ(res, 0); 397 EXPECT_EQ(labels_.count, 1U); 398 } 399 400 TEST_F(BpfLabelTest, jump_to_invalid_label) { 401 struct sock_filter test_jump[2]; 402 403 int id = bpf_label_id(&labels_, "test"); 404 set_bpf_jump_lbl(&test_jump[0], id + 1); 405 set_bpf_lbl(&test_jump[1], id); 406 407 int res = bpf_resolve_jumps(&labels_, test_jump, 2); 408 EXPECT_EQ(res, -1); 409 } 410 411 TEST_F(BpfLabelTest, jump_to_unresolved_label) { 412 struct sock_filter test_jump[2]; 413 414 int id = bpf_label_id(&labels_, "test"); 415 /* Notice the order of the instructions is reversed. */ 416 set_bpf_lbl(&test_jump[0], id); 417 set_bpf_jump_lbl(&test_jump[1], id); 418 419 int res = bpf_resolve_jumps(&labels_, test_jump, 2); 420 EXPECT_EQ(res, -1); 421 } 422 423 TEST_F(BpfLabelTest, too_many_labels) { 424 unsigned int i; 425 char label[20]; 426 427 for (i = 0; i < BPF_LABELS_MAX; i++) { 428 snprintf(label, 20, "test%u", i); 429 (void) bpf_label_id(&labels_, label); 430 } 431 int id = bpf_label_id(&labels_, "test"); 432 433 /* Insertion failed... */ 434 EXPECT_EQ(id, -1); 435 /* ... because the label lookup table is full. */ 436 EXPECT_EQ(labels_.count, BPF_LABELS_MAX); 437 } 438 439 class ArgFilterTest : public ::testing::Test { 440 protected: 441 virtual void SetUp() { 442 labels_.count = 0; 443 state_.filename = "policy"; 444 state_.line_number = 1; 445 } 446 virtual void TearDown() { free_label_strings(&labels_); } 447 struct bpf_labels labels_; 448 int nr_ = 1; 449 unsigned int id_ = 0; 450 struct parser_state state_; 451 }; 452 453 TEST_F(ArgFilterTest, empty_atom) { 454 std::string fragment = ""; 455 456 struct filter_block* block = 457 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 458 ASSERT_EQ(block, nullptr); 459 } 460 461 TEST_F(ArgFilterTest, whitespace_atom) { 462 std::string fragment = "\t "; 463 464 struct filter_block* block = 465 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 466 ASSERT_EQ(block, nullptr); 467 } 468 469 TEST_F(ArgFilterTest, no_comparison) { 470 std::string fragment = "arg0"; 471 472 struct filter_block* block = 473 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 474 ASSERT_EQ(block, nullptr); 475 } 476 477 TEST_F(ArgFilterTest, no_constant) { 478 std::string fragment = "arg0 =="; 479 480 struct filter_block* block = 481 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 482 ASSERT_EQ(block, nullptr); 483 } 484 485 TEST_F(ArgFilterTest, arg0_equals) { 486 std::string fragment = "arg0 == 0"; 487 488 struct filter_block* block = 489 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 490 491 ASSERT_NE(block, nullptr); 492 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 493 EXPECT_EQ(block->total_len, exp_total_len); 494 495 /* First block is a label. */ 496 struct filter_block *curr_block = block; 497 ASSERT_NE(curr_block, nullptr); 498 EXPECT_EQ(curr_block->len, 1U); 499 EXPECT_LBL(curr_block->instrs); 500 501 /* Second block is a comparison. */ 502 curr_block = curr_block->next; 503 EXPECT_COMP(curr_block); 504 505 /* Third block is a jump and a label (end of AND group). */ 506 curr_block = curr_block->next; 507 ASSERT_NE(curr_block, nullptr); 508 EXPECT_GROUP_END(curr_block); 509 510 /* Fourth block is SECCOMP_RET_KILL. */ 511 curr_block = curr_block->next; 512 ASSERT_NE(curr_block, nullptr); 513 EXPECT_KILL(curr_block); 514 515 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 516 curr_block = curr_block->next; 517 ASSERT_NE(curr_block, nullptr); 518 EXPECT_ALLOW(curr_block); 519 520 EXPECT_EQ(curr_block->next, nullptr); 521 522 free_block_list(block); 523 } 524 525 TEST_F(ArgFilterTest, arg0_short_gt_ge_comparisons) { 526 for (std::string fragment : 527 {"arg1 < 0xff", "arg1 <= 0xff", "arg1 > 0xff", "arg1 >= 0xff"}) { 528 struct filter_block* block = 529 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 530 531 ASSERT_NE(block, nullptr); 532 size_t exp_total_len = 1 + (BPF_ARG_SHORT_GT_GE_COMP_LEN + 1) + 2 + 1 + 2; 533 EXPECT_EQ(block->total_len, exp_total_len); 534 535 // First block is a label. 536 struct filter_block* curr_block = block; 537 ASSERT_NE(curr_block, nullptr); 538 EXPECT_EQ(curr_block->len, 1U); 539 EXPECT_LBL(curr_block->instrs); 540 541 // Second block is a short gt/ge comparison. 542 curr_block = curr_block->next; 543 EXPECT_SHORT_GT_GE_COMP(curr_block); 544 545 // Third block is a jump and a label (end of AND group). 546 curr_block = curr_block->next; 547 ASSERT_NE(curr_block, nullptr); 548 EXPECT_GROUP_END(curr_block); 549 550 // Fourth block is SECCOMP_RET_KILL. 551 curr_block = curr_block->next; 552 ASSERT_NE(curr_block, nullptr); 553 EXPECT_KILL(curr_block); 554 555 // Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. 556 curr_block = curr_block->next; 557 ASSERT_NE(curr_block, nullptr); 558 EXPECT_ALLOW(curr_block); 559 560 EXPECT_EQ(curr_block->next, nullptr); 561 562 free_block_list(block); 563 } 564 } 565 566 #if defined(BITS64) 567 TEST_F(ArgFilterTest, arg0_long_gt_ge_comparisons) { 568 for (std::string fragment : 569 {"arg1 < 0xbadc0ffee0ddf00d", "arg1 <= 0xbadc0ffee0ddf00d", 570 "arg1 > 0xbadc0ffee0ddf00d", "arg1 >= 0xbadc0ffee0ddf00d"}) { 571 struct filter_block* block = 572 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 573 574 ASSERT_NE(block, nullptr); 575 size_t exp_total_len = 1 + (BPF_ARG_GT_GE_COMP_LEN + 1) + 2 + 1 + 2; 576 EXPECT_EQ(block->total_len, exp_total_len); 577 578 // First block is a label. 579 struct filter_block* curr_block = block; 580 ASSERT_NE(curr_block, nullptr); 581 EXPECT_EQ(curr_block->len, 1U); 582 EXPECT_LBL(curr_block->instrs); 583 584 // Second block is a gt/ge comparison. 585 curr_block = curr_block->next; 586 EXPECT_GT_GE_COMP(curr_block); 587 588 // Third block is a jump and a label (end of AND group). 589 curr_block = curr_block->next; 590 ASSERT_NE(curr_block, nullptr); 591 EXPECT_GROUP_END(curr_block); 592 593 // Fourth block is SECCOMP_RET_KILL. 594 curr_block = curr_block->next; 595 ASSERT_NE(curr_block, nullptr); 596 EXPECT_KILL(curr_block); 597 598 // Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. 599 curr_block = curr_block->next; 600 ASSERT_NE(curr_block, nullptr); 601 EXPECT_ALLOW(curr_block); 602 603 EXPECT_EQ(curr_block->next, nullptr); 604 605 free_block_list(block); 606 } 607 } 608 #endif 609 610 TEST_F(ArgFilterTest, arg0_mask) { 611 std::string fragment = "arg1 & O_RDWR"; 612 613 struct filter_block* block = 614 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 615 616 ASSERT_NE(block, nullptr); 617 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 618 EXPECT_EQ(block->total_len, exp_total_len); 619 620 /* First block is a label. */ 621 struct filter_block *curr_block = block; 622 ASSERT_NE(curr_block, nullptr); 623 EXPECT_EQ(curr_block->len, 1U); 624 EXPECT_LBL(curr_block->instrs); 625 626 /* Second block is a comparison. */ 627 curr_block = curr_block->next; 628 EXPECT_COMP(curr_block); 629 630 /* Third block is a jump and a label (end of AND group). */ 631 curr_block = curr_block->next; 632 ASSERT_NE(curr_block, nullptr); 633 EXPECT_GROUP_END(curr_block); 634 635 /* Fourth block is SECCOMP_RET_KILL. */ 636 curr_block = curr_block->next; 637 ASSERT_NE(curr_block, nullptr); 638 EXPECT_KILL(curr_block); 639 640 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 641 curr_block = curr_block->next; 642 ASSERT_NE(curr_block, nullptr); 643 EXPECT_ALLOW(curr_block); 644 645 EXPECT_EQ(curr_block->next, nullptr); 646 647 free_block_list(block); 648 } 649 650 TEST_F(ArgFilterTest, arg0_flag_set_inclusion) { 651 std::string fragment = "arg0 in O_RDONLY|O_CREAT"; 652 653 struct filter_block* block = 654 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 655 656 ASSERT_NE(block, nullptr); 657 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 658 EXPECT_EQ(block->total_len, exp_total_len); 659 660 /* First block is a label. */ 661 struct filter_block *curr_block = block; 662 ASSERT_NE(curr_block, nullptr); 663 EXPECT_EQ(curr_block->len, 1U); 664 EXPECT_LBL(curr_block->instrs); 665 666 /* Second block is a comparison. */ 667 curr_block = curr_block->next; 668 ASSERT_NE(curr_block, nullptr); 669 EXPECT_COMP(curr_block); 670 671 /* Third block is a jump and a label (end of AND group). */ 672 curr_block = curr_block->next; 673 ASSERT_NE(curr_block, nullptr); 674 EXPECT_GROUP_END(curr_block); 675 676 /* Fourth block is SECCOMP_RET_KILL. */ 677 curr_block = curr_block->next; 678 ASSERT_NE(curr_block, nullptr); 679 EXPECT_KILL(curr_block); 680 681 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 682 curr_block = curr_block->next; 683 ASSERT_NE(curr_block, nullptr); 684 EXPECT_ALLOW(curr_block); 685 686 EXPECT_EQ(curr_block->next, nullptr); 687 688 free_block_list(block); 689 } 690 691 TEST_F(ArgFilterTest, arg0_eq_mask) { 692 std::string fragment = "arg1 == O_WRONLY|O_CREAT"; 693 694 struct filter_block* block = 695 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 696 697 ASSERT_NE(block, nullptr); 698 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 699 EXPECT_EQ(block->total_len, exp_total_len); 700 701 /* First block is a label. */ 702 struct filter_block *curr_block = block; 703 ASSERT_NE(curr_block, nullptr); 704 EXPECT_EQ(curr_block->len, 1U); 705 EXPECT_LBL(curr_block->instrs); 706 707 /* Second block is a comparison. */ 708 curr_block = curr_block->next; 709 ASSERT_NE(curr_block, nullptr); 710 EXPECT_COMP(curr_block); 711 EXPECT_EQ(curr_block->instrs[BPF_ARG_COMP_LEN - 1].k, 712 (unsigned int)(O_WRONLY | O_CREAT)); 713 714 /* Third block is a jump and a label (end of AND group). */ 715 curr_block = curr_block->next; 716 ASSERT_NE(curr_block, nullptr); 717 EXPECT_GROUP_END(curr_block); 718 719 /* Fourth block is SECCOMP_RET_KILL. */ 720 curr_block = curr_block->next; 721 ASSERT_NE(curr_block, nullptr); 722 EXPECT_KILL(curr_block); 723 724 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 725 curr_block = curr_block->next; 726 ASSERT_NE(curr_block, nullptr); 727 EXPECT_ALLOW(curr_block); 728 729 EXPECT_EQ(curr_block->next, nullptr); 730 731 free_block_list(block); 732 } 733 734 TEST_F(ArgFilterTest, and_or) { 735 std::string fragment = "arg0 == 0 && arg1 == 0 || arg0 == 1"; 736 737 struct filter_block* block = 738 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 739 ASSERT_NE(block, nullptr); 740 size_t exp_total_len = 1 + 3 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2; 741 EXPECT_EQ(block->total_len, exp_total_len); 742 743 /* First block is a label. */ 744 struct filter_block *curr_block = block; 745 ASSERT_NE(curr_block, nullptr); 746 EXPECT_EQ(curr_block->len, 1U); 747 EXPECT_LBL(curr_block->instrs); 748 749 /* Second block is a comparison ("arg0 == 0"). */ 750 curr_block = curr_block->next; 751 ASSERT_NE(curr_block, nullptr); 752 EXPECT_COMP(curr_block); 753 754 /* Third block is a comparison ("arg1 == 0"). */ 755 curr_block = curr_block->next; 756 ASSERT_NE(curr_block, nullptr); 757 EXPECT_COMP(curr_block); 758 759 /* Fourth block is a jump and a label (end of AND group). */ 760 curr_block = curr_block->next; 761 ASSERT_NE(curr_block, nullptr); 762 EXPECT_GROUP_END(curr_block); 763 764 /* Fifth block is a comparison ("arg0 == 1"). */ 765 curr_block = curr_block->next; 766 ASSERT_NE(curr_block, nullptr); 767 EXPECT_COMP(curr_block); 768 769 /* Sixth block is a jump and a label (end of AND group). */ 770 curr_block = curr_block->next; 771 ASSERT_NE(curr_block, nullptr); 772 EXPECT_GROUP_END(curr_block); 773 774 /* Seventh block is SECCOMP_RET_KILL. */ 775 curr_block = curr_block->next; 776 ASSERT_NE(curr_block, nullptr); 777 EXPECT_KILL(curr_block); 778 779 /* Eigth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 780 curr_block = curr_block->next; 781 ASSERT_NE(curr_block, nullptr); 782 EXPECT_ALLOW(curr_block); 783 784 EXPECT_EQ(curr_block->next, nullptr); 785 786 free_block_list(block); 787 } 788 789 TEST_F(ArgFilterTest, ret_errno) { 790 std::string fragment = "arg0 == 0 || arg0 == 1; return 1"; 791 792 struct filter_block* block = 793 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 794 ASSERT_NE(block, nullptr); 795 size_t exp_total_len = 1 + 2 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2; 796 EXPECT_EQ(block->total_len, exp_total_len); 797 798 /* First block is a label. */ 799 struct filter_block *curr_block = block; 800 ASSERT_NE(curr_block, nullptr); 801 EXPECT_EQ(curr_block->len, 1U); 802 EXPECT_LBL(curr_block->instrs); 803 804 /* Second block is a comparison ("arg0 == 0"). */ 805 curr_block = curr_block->next; 806 ASSERT_NE(curr_block, nullptr); 807 EXPECT_COMP(curr_block); 808 809 /* Third block is a jump and a label (end of AND group). */ 810 curr_block = curr_block->next; 811 ASSERT_NE(curr_block, nullptr); 812 EXPECT_GROUP_END(curr_block); 813 814 /* Fourth block is a comparison ("arg0 == 1"). */ 815 curr_block = curr_block->next; 816 ASSERT_NE(curr_block, nullptr); 817 EXPECT_COMP(curr_block); 818 819 /* Fifth block is a jump and a label (end of AND group). */ 820 curr_block = curr_block->next; 821 ASSERT_NE(curr_block, nullptr); 822 EXPECT_GROUP_END(curr_block); 823 824 /* Sixth block is SECCOMP_RET_ERRNO. */ 825 curr_block = curr_block->next; 826 ASSERT_NE(curr_block, nullptr); 827 EXPECT_EQ(curr_block->len, 1U); 828 EXPECT_EQ_STMT(curr_block->instrs, 829 BPF_RET + BPF_K, 830 SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA)); 831 832 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 833 curr_block = curr_block->next; 834 ASSERT_NE(curr_block, nullptr); 835 EXPECT_ALLOW(curr_block); 836 837 EXPECT_EQ(curr_block->next, nullptr); 838 839 free_block_list(block); 840 } 841 842 TEST_F(ArgFilterTest, unconditional_errno) { 843 std::string fragment = "return 1"; 844 845 struct filter_block* block = 846 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 847 ASSERT_NE(block, nullptr); 848 size_t exp_total_len = 2; 849 EXPECT_EQ(block->total_len, exp_total_len); 850 851 /* First block is a label. */ 852 struct filter_block *curr_block = block; 853 ASSERT_NE(curr_block, nullptr); 854 EXPECT_EQ(curr_block->len, 1U); 855 EXPECT_LBL(curr_block->instrs); 856 857 /* Second block is SECCOMP_RET_ERRNO. */ 858 curr_block = curr_block->next; 859 ASSERT_NE(curr_block, nullptr); 860 EXPECT_EQ(curr_block->len, 1U); 861 EXPECT_EQ_STMT(curr_block->instrs, 862 BPF_RET + BPF_K, 863 SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA)); 864 865 EXPECT_EQ(curr_block->next, nullptr); 866 867 free_block_list(block); 868 } 869 870 TEST_F(ArgFilterTest, invalid_arg_token) { 871 std::string fragment = "org0 == 0"; 872 873 struct filter_block* block = 874 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 875 ASSERT_EQ(block, nullptr); 876 } 877 878 TEST_F(ArgFilterTest, invalid_arg_number) { 879 std::string fragment = "argnn == 0"; 880 881 struct filter_block* block = 882 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 883 ASSERT_EQ(block, nullptr); 884 } 885 886 TEST_F(ArgFilterTest, extra_chars_in_arg_token) { 887 std::string fragment = "arg0n == 0"; 888 889 struct filter_block* block = 890 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 891 ASSERT_EQ(block, nullptr); 892 } 893 894 TEST_F(ArgFilterTest, invalid_operator) { 895 std::string fragment = "arg0 invalidop 0"; 896 897 struct filter_block* block = 898 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 899 ASSERT_EQ(block, nullptr); 900 } 901 902 TEST_F(ArgFilterTest, invalid_constant) { 903 std::string fragment = "arg0 == INVALIDCONSTANT"; 904 905 struct filter_block* block = 906 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 907 ASSERT_EQ(block, nullptr); 908 } 909 910 TEST_F(ArgFilterTest, extra_tokens) { 911 std::string fragment = "arg0 == 0 EXTRATOKEN"; 912 913 struct filter_block* block = 914 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 915 ASSERT_EQ(block, nullptr); 916 } 917 918 TEST_F(ArgFilterTest, invalid_errno) { 919 std::string fragment = "arg0 == 0 && arg1 == 1; return errno"; 920 921 struct filter_block* block = 922 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 923 ASSERT_EQ(block, nullptr); 924 } 925 926 TEST_F(ArgFilterTest, log_no_ret_error) { 927 std::string fragment = "arg0 == 0"; 928 929 struct filter_block* block = 930 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_, 931 USE_RET_TRAP); 932 933 ASSERT_NE(block, nullptr); 934 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 935 EXPECT_EQ(block->total_len, exp_total_len); 936 937 /* First block is a label. */ 938 struct filter_block *curr_block = block; 939 ASSERT_NE(curr_block, nullptr); 940 EXPECT_EQ(curr_block->len, 1U); 941 EXPECT_LBL(curr_block->instrs); 942 943 /* Second block is a comparison. */ 944 curr_block = curr_block->next; 945 ASSERT_NE(curr_block, nullptr); 946 EXPECT_COMP(curr_block); 947 948 /* Third block is a jump and a label (end of AND group). */ 949 curr_block = curr_block->next; 950 ASSERT_NE(curr_block, nullptr); 951 EXPECT_GROUP_END(curr_block); 952 953 /* Fourth block is SECCOMP_RET_TRAP, with no errno. */ 954 curr_block = curr_block->next; 955 ASSERT_NE(curr_block, nullptr); 956 EXPECT_TRAP(curr_block); 957 958 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 959 curr_block = curr_block->next; 960 ASSERT_NE(curr_block, nullptr); 961 EXPECT_ALLOW(curr_block); 962 963 EXPECT_EQ(curr_block->next, nullptr); 964 965 free_block_list(block); 966 } 967 968 TEST_F(ArgFilterTest, log_bad_ret_error) { 969 std::string fragment = "arg0 == 0; return"; 970 971 struct filter_block* block = 972 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_); 973 ASSERT_NE(block, nullptr); 974 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 975 EXPECT_EQ(block->total_len, exp_total_len); 976 977 /* First block is a label. */ 978 struct filter_block *curr_block = block; 979 ASSERT_NE(curr_block, nullptr); 980 EXPECT_EQ(curr_block->len, 1U); 981 EXPECT_LBL(curr_block->instrs); 982 983 /* Second block is a comparison ("arg0 == 0"). */ 984 curr_block = curr_block->next; 985 ASSERT_NE(curr_block, nullptr); 986 EXPECT_COMP(curr_block); 987 988 /* Third block is a jump and a label (end of AND group). */ 989 curr_block = curr_block->next; 990 ASSERT_NE(curr_block, nullptr); 991 EXPECT_GROUP_END(curr_block); 992 993 /* 994 * Sixth block is NOT SECCOMP_RET_ERRNO, it should be SECCOMP_RET_KILL. 995 */ 996 curr_block = curr_block->next; 997 ASSERT_NE(curr_block, nullptr); 998 EXPECT_KILL(curr_block); 999 1000 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 1001 curr_block = curr_block->next; 1002 ASSERT_NE(curr_block, nullptr); 1003 EXPECT_ALLOW(curr_block); 1004 1005 EXPECT_EQ(curr_block->next, nullptr); 1006 1007 free_block_list(block); 1008 } 1009 1010 TEST_F(ArgFilterTest, no_log_bad_ret_error) { 1011 std::string fragment = "arg0 == 0; return"; 1012 1013 struct filter_block* block = 1014 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_, 1015 USE_RET_TRAP); 1016 ASSERT_NE(block, nullptr); 1017 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 1018 EXPECT_EQ(block->total_len, exp_total_len); 1019 1020 /* First block is a label. */ 1021 struct filter_block *curr_block = block; 1022 ASSERT_NE(curr_block, nullptr); 1023 EXPECT_EQ(curr_block->len, 1U); 1024 EXPECT_LBL(curr_block->instrs); 1025 1026 /* Second block is a comparison ("arg0 == 0"). */ 1027 curr_block = curr_block->next; 1028 ASSERT_NE(curr_block, nullptr); 1029 EXPECT_COMP(curr_block); 1030 1031 /* Third block is a jump and a label (end of AND group). */ 1032 curr_block = curr_block->next; 1033 ASSERT_NE(curr_block, nullptr); 1034 EXPECT_GROUP_END(curr_block); 1035 1036 /* 1037 * Sixth block is *not* SECCOMP_RET_ERRNO, it should be 1038 * SECCOMP_RET_TRAP. 1039 */ 1040 curr_block = curr_block->next; 1041 ASSERT_NE(curr_block, nullptr); 1042 EXPECT_TRAP(curr_block); 1043 1044 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 1045 curr_block = curr_block->next; 1046 ASSERT_NE(curr_block, nullptr); 1047 EXPECT_ALLOW(curr_block); 1048 1049 EXPECT_EQ(curr_block->next, nullptr); 1050 1051 free_block_list(block); 1052 } 1053 1054 namespace { 1055 1056 FILE* write_policy_to_pipe(std::string policy) { 1057 int pipefd[2]; 1058 if (pipe(pipefd) == -1) { 1059 pwarn("pipe(pipefd) failed"); 1060 return nullptr; 1061 } 1062 1063 size_t len = policy.length(); 1064 size_t i = 0; 1065 unsigned int attempts = 0; 1066 ssize_t ret; 1067 while (i < len) { 1068 ret = write(pipefd[1], policy.c_str() + i, len - i); 1069 if (ret == -1) { 1070 close(pipefd[0]); 1071 close(pipefd[1]); 1072 return nullptr; 1073 } 1074 1075 /* If we write 0 bytes three times in a row, fail. */ 1076 if (ret == 0) { 1077 if (++attempts >= 3) { 1078 close(pipefd[0]); 1079 close(pipefd[1]); 1080 warn("write() returned 0 three times in a row"); 1081 return nullptr; 1082 } 1083 continue; 1084 } 1085 1086 attempts = 0; 1087 i += (size_t)ret; 1088 } 1089 1090 close(pipefd[1]); 1091 return fdopen(pipefd[0], "r"); 1092 } 1093 1094 class FileTest : public ::testing::Test { 1095 protected: 1096 virtual void SetUp() { 1097 labels_.count = 0; 1098 head_ = new_filter_block(); 1099 arg_blocks_ = nullptr; 1100 } 1101 virtual void TearDown() { 1102 free_label_strings(&labels_); 1103 free_block_list(head_); 1104 free_block_list(arg_blocks_); 1105 } 1106 struct bpf_labels labels_; 1107 struct filter_block *head_; 1108 struct filter_block *arg_blocks_; 1109 }; 1110 1111 } // namespace 1112 1113 TEST_F(FileTest, malformed_policy) { 1114 std::string policy = 1115 "malformed"; 1116 1117 FILE* policy_file = write_policy_to_pipe(policy); 1118 ASSERT_NE(policy_file, nullptr); 1119 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_, 1120 &labels_); 1121 fclose(policy_file); 1122 1123 /* 1124 * Policy is malformed, but process should not crash. 1125 */ 1126 ASSERT_EQ(res, -1); 1127 } 1128 1129 TEST_F(FileTest, double_free_on_compile_error) { 1130 std::string policy = 1131 "read:arg0 == 0\n" 1132 "write:0"; 1133 1134 FILE* policy_file = write_policy_to_pipe(policy); 1135 ASSERT_NE(policy_file, nullptr); 1136 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_, 1137 &labels_); 1138 fclose(policy_file); 1139 1140 /* 1141 * Policy is malformed, but process should not crash. 1142 */ 1143 ASSERT_EQ(res, -1); 1144 } 1145 1146 TEST_F(FileTest, invalid_return) { 1147 std::string policy = 1148 "read:arg0 == 0; ;"; 1149 1150 FILE* policy_file = write_policy_to_pipe(policy); 1151 ASSERT_NE(policy_file, nullptr); 1152 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_, 1153 &labels_); 1154 fclose(policy_file); 1155 1156 /* 1157 * Policy is malformed, but process should not crash. 1158 */ 1159 ASSERT_EQ(res, -1); 1160 } 1161 1162 TEST_F(FileTest, seccomp_mode1) { 1163 std::string policy = 1164 "read: 1\n" 1165 "write: 1\n" 1166 "rt_sigreturn: 1\n" 1167 "exit: 1\n"; 1168 1169 FILE* policy_file = write_policy_to_pipe(policy); 1170 ASSERT_NE(policy_file, nullptr); 1171 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_, 1172 &labels_); 1173 fclose(policy_file); 1174 1175 /* 1176 * Checks return value and that the blocks only allow expected syscalls. 1177 */ 1178 ASSERT_EQ(res, 0); 1179 struct filter_block *curr_block = head_; 1180 ASSERT_NE(curr_block, nullptr); 1181 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_read); 1182 curr_block = curr_block->next; 1183 ASSERT_NE(curr_block, nullptr); 1184 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_write); 1185 curr_block = curr_block->next; 1186 ASSERT_NE(curr_block, nullptr); 1187 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_rt_sigreturn); 1188 curr_block = curr_block->next; 1189 ASSERT_NE(curr_block, nullptr); 1190 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_exit); 1191 1192 EXPECT_EQ(curr_block->next, nullptr); 1193 } 1194 1195 TEST_F(FileTest, seccomp_read) { 1196 std::string policy = 1197 "read: arg0 == 0\n" 1198 "write: 1\n" 1199 "rt_sigreturn: 1\n" 1200 "exit: 1\n"; 1201 1202 const int LABEL_ID = 0; 1203 1204 FILE* policy_file = write_policy_to_pipe(policy); 1205 ASSERT_NE(policy_file, nullptr); 1206 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_, 1207 &labels_); 1208 fclose(policy_file); 1209 1210 /* 1211 * Checks return value, that the blocks only allow expected syscalls, and that 1212 * labels between |head_| and |arg_blocks_| match. 1213 */ 1214 ASSERT_EQ(res, 0); 1215 struct filter_block *curr_block = head_; 1216 ASSERT_NE(curr_block, nullptr); 1217 EXPECT_ALLOW_SYSCALL_ARGS(curr_block->instrs, 1218 __NR_read, 1219 LABEL_ID, 1220 JUMP_JT, 1221 JUMP_JF); 1222 curr_block = curr_block->next; 1223 ASSERT_NE(curr_block, nullptr); 1224 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_write); 1225 curr_block = curr_block->next; 1226 ASSERT_NE(curr_block, nullptr); 1227 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_rt_sigreturn); 1228 curr_block = curr_block->next; 1229 ASSERT_NE(curr_block, nullptr); 1230 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_exit); 1231 1232 ASSERT_NE(arg_blocks_, nullptr); 1233 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2; 1234 EXPECT_EQ(arg_blocks_->total_len, exp_total_len); 1235 1236 /* First block is a label. */ 1237 curr_block = arg_blocks_; 1238 ASSERT_NE(curr_block, nullptr); 1239 EXPECT_EQ(curr_block->len, 1U); 1240 EXPECT_ACTUAL_LBL(curr_block->instrs, LABEL_ID); 1241 1242 /* Second block is a comparison. */ 1243 curr_block = curr_block->next; 1244 EXPECT_COMP(curr_block); 1245 1246 /* Third block is a jump and a label (end of AND group). */ 1247 curr_block = curr_block->next; 1248 ASSERT_NE(curr_block, nullptr); 1249 EXPECT_GROUP_END(curr_block); 1250 1251 /* Fourth block is SECCOMP_RET_KILL. */ 1252 curr_block = curr_block->next; 1253 ASSERT_NE(curr_block, nullptr); 1254 EXPECT_KILL(curr_block); 1255 1256 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */ 1257 curr_block = curr_block->next; 1258 ASSERT_NE(curr_block, nullptr); 1259 EXPECT_ALLOW(curr_block); 1260 1261 EXPECT_EQ(curr_block->next, nullptr); 1262 } 1263 1264 TEST_F(FileTest, multiline) { 1265 std::string policy = 1266 "read:\\\n1\n" 1267 "openat:arg0 in\\\n5"; 1268 1269 const int LABEL_ID = 0; 1270 1271 FILE* policy_file = write_policy_to_pipe(policy); 1272 ASSERT_NE(policy_file, nullptr); 1273 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_, 1274 &labels_); 1275 fclose(policy_file); 1276 1277 /* 1278 * Policy should be valid. 1279 */ 1280 ASSERT_EQ(res, 0); 1281 1282 /* First block is the read. */ 1283 struct filter_block *curr_block = head_; 1284 ASSERT_NE(curr_block, nullptr); 1285 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_read); 1286 1287 /* Second block is the open. */ 1288 curr_block = curr_block->next; 1289 ASSERT_NE(curr_block, nullptr); 1290 EXPECT_ALLOW_SYSCALL_ARGS(curr_block->instrs, 1291 __NR_openat, 1292 LABEL_ID, 1293 JUMP_JT, 1294 JUMP_JF); 1295 1296 EXPECT_EQ(curr_block->next, nullptr); 1297 } 1298 1299 TEST(FilterTest, seccomp_mode1) { 1300 struct sock_fprog actual; 1301 std::string policy = 1302 "read: 1\n" 1303 "write: 1\n" 1304 "rt_sigreturn: 1\n" 1305 "exit: 1\n"; 1306 1307 FILE* policy_file = write_policy_to_pipe(policy); 1308 ASSERT_NE(policy_file, nullptr); 1309 1310 int res = test_compile_filter("policy", policy_file, &actual); 1311 fclose(policy_file); 1312 1313 /* 1314 * Checks return value, filter length, and that the filter 1315 * validates arch, loads syscall number, and 1316 * only allows expected syscalls. 1317 */ 1318 ASSERT_EQ(res, 0); 1319 EXPECT_EQ(actual.len, 13); 1320 EXPECT_ARCH_VALIDATION(actual.filter); 1321 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, 1322 BPF_LD + BPF_W + BPF_ABS, 1323 syscall_nr); 1324 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read); 1325 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3, __NR_write); 1326 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5, 1327 __NR_rt_sigreturn); 1328 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit); 1329 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, 1330 BPF_RET + BPF_K, 1331 SECCOMP_RET_KILL); 1332 1333 free(actual.filter); 1334 } 1335 1336 TEST(FilterTest, seccomp_mode1_trap) { 1337 struct sock_fprog actual; 1338 std::string policy = 1339 "read: 1\n" 1340 "write: 1\n" 1341 "rt_sigreturn: 1\n" 1342 "exit: 1\n"; 1343 1344 FILE* policy_file = write_policy_to_pipe(policy); 1345 ASSERT_NE(policy_file, nullptr); 1346 1347 int res = test_compile_filter("policy", policy_file, &actual, USE_RET_TRAP); 1348 fclose(policy_file); 1349 1350 /* 1351 * Checks return value, filter length, and that the filter 1352 * validates arch, loads syscall number, and 1353 * only allows expected syscalls. 1354 */ 1355 ASSERT_EQ(res, 0); 1356 EXPECT_EQ(actual.len, 13); 1357 EXPECT_ARCH_VALIDATION(actual.filter); 1358 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, 1359 BPF_LD+BPF_W+BPF_ABS, syscall_nr); 1360 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1, 1361 __NR_read); 1362 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3, 1363 __NR_write); 1364 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5, 1365 __NR_rt_sigreturn); 1366 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, 1367 __NR_exit); 1368 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K, 1369 SECCOMP_RET_TRAP); 1370 1371 free(actual.filter); 1372 } 1373 1374 TEST(FilterTest, seccomp_read_write) { 1375 struct sock_fprog actual; 1376 std::string policy = 1377 "read: arg0 == 0\n" 1378 "write: arg0 == 1 || arg0 == 2\n" 1379 "rt_sigreturn: 1\n" 1380 "exit: 1\n"; 1381 1382 FILE* policy_file = write_policy_to_pipe(policy); 1383 ASSERT_NE(policy_file, nullptr); 1384 1385 int res = test_compile_filter("policy", policy_file, &actual); 1386 fclose(policy_file); 1387 1388 /* 1389 * Checks return value, filter length, and that the filter 1390 * validates arch, loads syscall number, and 1391 * only allows expected syscalls, jumping to correct arg filter 1392 * offsets. 1393 */ 1394 ASSERT_EQ(res, 0); 1395 size_t exp_total_len = 27 + 3 * (BPF_ARG_COMP_LEN + 1); 1396 EXPECT_EQ(actual.len, exp_total_len); 1397 1398 EXPECT_ARCH_VALIDATION(actual.filter); 1399 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, 1400 BPF_LD + BPF_W + BPF_ABS, 1401 syscall_nr); 1402 EXPECT_ALLOW_SYSCALL_ARGS( 1403 actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read, 7, 0, 0); 1404 EXPECT_ALLOW_SYSCALL_ARGS(actual.filter + ARCH_VALIDATION_LEN + 3, 1405 __NR_write, 1406 12 + BPF_ARG_COMP_LEN, 1407 0, 1408 0); 1409 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5, 1410 __NR_rt_sigreturn); 1411 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit); 1412 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, 1413 BPF_RET + BPF_K, 1414 SECCOMP_RET_KILL); 1415 1416 free(actual.filter); 1417 } 1418 1419 TEST(FilterTest, misplaced_whitespace) { 1420 struct sock_fprog actual; 1421 std::string policy = "read :1\n"; 1422 1423 FILE* policy_file = write_policy_to_pipe(policy); 1424 ASSERT_NE(policy_file, nullptr); 1425 1426 int res = test_compile_filter("policy", policy_file, &actual); 1427 fclose(policy_file); 1428 1429 /* Checks return value and filter length. */ 1430 ASSERT_EQ(res, 0); 1431 EXPECT_EQ(actual.len, 1432 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ + ALLOW_SYSCALL_LEN + 1433 1 /* ret kill */); 1434 free(actual.filter); 1435 } 1436 1437 TEST(FilterTest, missing_atom) { 1438 struct sock_fprog actual; 1439 std::string policy = "open:\n"; 1440 1441 FILE* policy_file = write_policy_to_pipe(policy); 1442 ASSERT_NE(policy_file, nullptr); 1443 1444 int res = test_compile_filter("policy", policy_file, &actual); 1445 fclose(policy_file); 1446 ASSERT_NE(res, 0); 1447 } 1448 1449 TEST(FilterTest, whitespace_atom) { 1450 struct sock_fprog actual; 1451 std::string policy = "open:\t \n"; 1452 1453 FILE* policy_file = write_policy_to_pipe(policy); 1454 ASSERT_NE(policy_file, nullptr); 1455 1456 int res = test_compile_filter("policy", policy_file, &actual); 1457 fclose(policy_file); 1458 ASSERT_NE(res, 0); 1459 } 1460 1461 TEST(FilterTest, invalid_name) { 1462 struct sock_fprog actual; 1463 std::string policy = "notasyscall: 1\n"; 1464 1465 FILE* policy_file = write_policy_to_pipe(policy); 1466 ASSERT_NE(policy_file, nullptr); 1467 1468 int res = test_compile_filter("policy", policy_file, &actual); 1469 fclose(policy_file); 1470 ASSERT_NE(res, 0); 1471 } 1472 1473 TEST(FilterTest, invalid_arg) { 1474 struct sock_fprog actual; 1475 std::string policy = "open: argnn ==\n"; 1476 1477 FILE* policy_file = write_policy_to_pipe(policy); 1478 ASSERT_NE(policy_file, nullptr); 1479 1480 int res = test_compile_filter("policy", policy_file, &actual); 1481 fclose(policy_file); 1482 ASSERT_NE(res, 0); 1483 } 1484 1485 TEST(FilterTest, invalid_tokens) { 1486 struct sock_fprog actual; 1487 std::string policy = "read: arg0 == 1 |||| arg0 == 2\n"; 1488 1489 FILE* policy_file = write_policy_to_pipe(policy); 1490 ASSERT_NE(policy_file, nullptr); 1491 1492 int res = test_compile_filter("policy", policy_file, &actual); 1493 fclose(policy_file); 1494 ASSERT_NE(res, 0); 1495 } 1496 1497 TEST(FilterTest, nonexistent) { 1498 struct sock_fprog actual; 1499 int res = test_compile_filter("policy", nullptr, &actual); 1500 ASSERT_NE(res, 0); 1501 } 1502 1503 TEST(FilterTest, log) { 1504 struct sock_fprog actual; 1505 std::string policy = 1506 "read: 1\n" 1507 "write: 1\n" 1508 "rt_sigreturn: 1\n" 1509 "exit: 1\n"; 1510 1511 FILE* policy_file = write_policy_to_pipe(policy); 1512 ASSERT_NE(policy_file, nullptr); 1513 1514 int res = test_compile_filter("policy", policy_file, &actual, USE_RET_TRAP, 1515 USE_LOGGING); 1516 fclose(policy_file); 1517 1518 size_t i; 1519 size_t index = 0; 1520 /* 1521 * Checks return value, filter length, and that the filter 1522 * validates arch, loads syscall number, only allows expected syscalls, 1523 * and returns TRAP on failure. 1524 * NOTE(jorgelo): the filter is longer since we add the syscalls needed 1525 * for logging. 1526 */ 1527 ASSERT_EQ(res, 0); 1528 EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len); 1529 EXPECT_ARCH_VALIDATION(actual.filter); 1530 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, 1531 BPF_LD + BPF_W + BPF_ABS, 1532 syscall_nr); 1533 1534 index = ARCH_VALIDATION_LEN + 1; 1535 for (i = 0; i < log_syscalls_len; i++) 1536 EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i), 1537 lookup_syscall(log_syscalls[i])); 1538 1539 index += 2 * log_syscalls_len; 1540 1541 EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read); 1542 EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write); 1543 EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn); 1544 EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit); 1545 EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET + BPF_K, SECCOMP_RET_TRAP); 1546 1547 free(actual.filter); 1548 } 1549 1550 TEST(FilterTest, allow_log_but_kill) { 1551 struct sock_fprog actual; 1552 std::string policy = 1553 "read: 1\n" 1554 "write: 1\n" 1555 "rt_sigreturn: 1\n" 1556 "exit: 1\n"; 1557 1558 FILE* policy_file = write_policy_to_pipe(policy); 1559 ASSERT_NE(policy_file, nullptr); 1560 1561 int res = test_compile_filter("policy", policy_file, &actual, USE_RET_KILL, 1562 USE_LOGGING); 1563 fclose(policy_file); 1564 1565 size_t i; 1566 size_t index = 0; 1567 /* 1568 * Checks return value, filter length, and that the filter 1569 * validates arch, loads syscall number, only allows expected syscalls, 1570 * and returns TRAP on failure. 1571 * NOTE(jorgelo): the filter is longer since we add the syscalls needed 1572 * for logging. 1573 */ 1574 ASSERT_EQ(res, 0); 1575 EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len); 1576 EXPECT_ARCH_VALIDATION(actual.filter); 1577 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, 1578 BPF_LD+BPF_W+BPF_ABS, syscall_nr); 1579 1580 index = ARCH_VALIDATION_LEN + 1; 1581 for (i = 0; i < log_syscalls_len; i++) 1582 EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i), 1583 lookup_syscall(log_syscalls[i])); 1584 1585 index += 2 * log_syscalls_len; 1586 1587 EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read); 1588 EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write); 1589 EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn); 1590 EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit); 1591 EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET+BPF_K, 1592 SECCOMP_RET_KILL); 1593 1594 free(actual.filter); 1595 } 1596 1597 TEST(FilterTest, include_invalid_token) { 1598 struct sock_fprog actual; 1599 std::string invalid_token = "@unclude ./test/seccomp.policy\n"; 1600 1601 FILE* policy_file = write_policy_to_pipe(invalid_token); 1602 ASSERT_NE(policy_file, nullptr); 1603 int res = test_compile_filter("policy", policy_file, &actual); 1604 fclose(policy_file); 1605 EXPECT_NE(res, 0); 1606 } 1607 1608 TEST(FilterTest, include_no_space) { 1609 struct sock_fprog actual; 1610 std::string no_space = "@includetest/seccomp.policy\n"; 1611 1612 FILE* policy_file = write_policy_to_pipe(no_space); 1613 ASSERT_NE(policy_file, nullptr); 1614 int res = test_compile_filter("policy", policy_file, &actual); 1615 fclose(policy_file); 1616 EXPECT_NE(res, 0); 1617 } 1618 1619 TEST(FilterTest, include_double_token) { 1620 struct sock_fprog actual; 1621 std::string double_token = "@includeinclude ./test/seccomp.policy\n"; 1622 1623 FILE* policy_file = write_policy_to_pipe(double_token); 1624 ASSERT_NE(policy_file, nullptr); 1625 int res = test_compile_filter("policy", policy_file, &actual); 1626 fclose(policy_file); 1627 EXPECT_NE(res, 0); 1628 } 1629 1630 TEST(FilterTest, include_no_file) { 1631 struct sock_fprog actual; 1632 std::string no_file = "@include\n"; 1633 1634 FILE* policy_file = write_policy_to_pipe(no_file); 1635 ASSERT_NE(policy_file, nullptr); 1636 int res = test_compile_filter("policy", policy_file, &actual); 1637 fclose(policy_file); 1638 EXPECT_NE(res, 0); 1639 } 1640 1641 TEST(FilterTest, include_space_no_file) { 1642 struct sock_fprog actual; 1643 std::string space_no_file = "@include \n"; 1644 1645 FILE* policy_file = write_policy_to_pipe(space_no_file); 1646 ASSERT_NE(policy_file, nullptr); 1647 int res = test_compile_filter("policy", policy_file, &actual); 1648 fclose(policy_file); 1649 EXPECT_NE(res, 0); 1650 } 1651 1652 TEST(FilterTest, include_implicit_relative_path) { 1653 struct sock_fprog actual; 1654 std::string implicit_relative_path = "@include test/seccomp.policy\n"; 1655 1656 FILE* policy_file = write_policy_to_pipe(implicit_relative_path); 1657 ASSERT_NE(policy_file, nullptr); 1658 int res = test_compile_filter("policy", policy_file, &actual); 1659 fclose(policy_file); 1660 EXPECT_NE(res, 0); 1661 } 1662 1663 TEST(FilterTest, include_extra_text) { 1664 struct sock_fprog actual; 1665 std::string extra_text = "@include /some/file: sneaky comment\n"; 1666 1667 FILE* policy_file = write_policy_to_pipe(extra_text); 1668 ASSERT_NE(policy_file, nullptr); 1669 int res = test_compile_filter("policy", policy_file, &actual); 1670 fclose(policy_file); 1671 EXPECT_NE(res, 0); 1672 } 1673 1674 TEST(FilterTest, include_split_filename) { 1675 struct sock_fprog actual; 1676 std::string split_filename = "@include /some/file:colon.policy\n"; 1677 1678 FILE* policy_file = write_policy_to_pipe(split_filename); 1679 ASSERT_NE(policy_file, nullptr); 1680 int res = test_compile_filter("policy", policy_file, &actual); 1681 fclose(policy_file); 1682 EXPECT_NE(res, 0); 1683 } 1684 1685 TEST(FilterTest, include_nonexistent_file) { 1686 struct sock_fprog actual; 1687 std::string include_policy = "@include ./nonexistent.policy\n"; 1688 1689 FILE* policy_file = write_policy_to_pipe(include_policy); 1690 ASSERT_NE(policy_file, nullptr); 1691 1692 int res = test_compile_filter("policy", policy_file, &actual); 1693 fclose(policy_file); 1694 1695 ASSERT_NE(res, 0); 1696 } 1697 1698 // TODO(jorgelo): Android unit tests don't currently support data files. 1699 // Re-enable by creating a temporary policy file at runtime. 1700 #if !defined(__ANDROID__) 1701 1702 TEST(FilterTest, include) { 1703 struct sock_fprog compiled_plain; 1704 struct sock_fprog compiled_with_include; 1705 1706 std::string policy_plain = 1707 "read: 1\n" 1708 "write: 1\n" 1709 "rt_sigreturn: 1\n" 1710 "exit: 1\n"; 1711 1712 FILE* file_plain = write_policy_to_pipe(policy_plain); 1713 ASSERT_NE(file_plain, nullptr); 1714 int res_plain = test_compile_filter("policy", file_plain, &compiled_plain, 1715 USE_RET_KILL); 1716 fclose(file_plain); 1717 1718 std::string policy_with_include = 1719 "@include " + source_path("test/seccomp.policy") + "\n"; 1720 1721 FILE* file_with_include = write_policy_to_pipe(policy_with_include); 1722 ASSERT_NE(file_with_include, nullptr); 1723 int res_with_include = 1724 test_compile_filter("policy", file_with_include, &compiled_with_include, 1725 USE_RET_KILL); 1726 fclose(file_with_include); 1727 1728 /* 1729 * Checks that filter length is the same for a plain policy and an equivalent 1730 * policy with an @include statement. Also checks that the filter generated 1731 * from the policy with an @include statement is exactly the same as one 1732 * generated from a plain policy. 1733 */ 1734 ASSERT_EQ(res_plain, 0); 1735 ASSERT_EQ(res_with_include, 0); 1736 1737 EXPECT_EQ(compiled_plain.len, 13); 1738 EXPECT_EQ(compiled_with_include.len, 13); 1739 1740 EXPECT_ARCH_VALIDATION(compiled_with_include.filter); 1741 EXPECT_EQ_STMT(compiled_with_include.filter + ARCH_VALIDATION_LEN, 1742 BPF_LD + BPF_W + BPF_ABS, 1743 syscall_nr); 1744 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 1, 1745 __NR_read); 1746 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 3, 1747 __NR_write); 1748 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 5, 1749 __NR_rt_sigreturn); 1750 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 7, 1751 __NR_exit); 1752 EXPECT_EQ_STMT(compiled_with_include.filter + ARCH_VALIDATION_LEN + 9, 1753 BPF_RET + BPF_K, 1754 SECCOMP_RET_KILL); 1755 1756 free(compiled_plain.filter); 1757 free(compiled_with_include.filter); 1758 } 1759 1760 TEST(FilterTest, include_same_syscalls) { 1761 struct sock_fprog actual; 1762 std::string policy = 1763 "read: 1\n" 1764 "write: 1\n" 1765 "rt_sigreturn: 1\n" 1766 "exit: 1\n" 1767 "@include " + source_path("test/seccomp.policy") + "\n"; 1768 1769 FILE* policy_file = write_policy_to_pipe(policy); 1770 ASSERT_NE(policy_file, nullptr); 1771 1772 int res = test_compile_filter("policy", policy_file, &actual); 1773 fclose(policy_file); 1774 1775 ASSERT_EQ(res, 0); 1776 EXPECT_EQ(actual.len, 1777 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ + 1778 2 * 8 /* check syscalls twice */ + 1 /* filter return */); 1779 free(actual.filter); 1780 } 1781 1782 TEST(FilterTest, include_two) { 1783 struct sock_fprog actual; 1784 std::string policy = 1785 "@include " + source_path("test/seccomp.policy") + "\n" + 1786 "@include " + source_path("test/seccomp.policy") + "\n"; 1787 1788 FILE* policy_file = write_policy_to_pipe(policy); 1789 ASSERT_NE(policy_file, nullptr); 1790 1791 int res = test_compile_filter("policy", policy_file, &actual); 1792 fclose(policy_file); 1793 1794 ASSERT_EQ(res, 0); 1795 EXPECT_EQ(actual.len, 1796 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ + 1797 2 * 8 /* check syscalls twice */ + 1 /* filter return */); 1798 free(actual.filter); 1799 } 1800 1801 TEST(FilterTest, include_invalid_policy) { 1802 struct sock_fprog actual; 1803 std::string policy = 1804 "read: 1\n" 1805 "write: 1\n" 1806 "rt_sigreturn: 1\n" 1807 "exit: 1\n" 1808 "@include ./test/invalid_syscall_name.policy\n"; 1809 1810 FILE* policy_file = write_policy_to_pipe(policy); 1811 ASSERT_NE(policy_file, nullptr); 1812 1813 /* Ensure the included (invalid) policy file exists. */ 1814 FILE* included_file = fopen( 1815 source_path("test/invalid_syscall_name.policy").c_str(), "re"); 1816 ASSERT_NE(included_file, nullptr); 1817 fclose(included_file); 1818 1819 int res = test_compile_filter("policy", policy_file, &actual); 1820 fclose(policy_file); 1821 1822 ASSERT_NE(res, 0); 1823 } 1824 1825 TEST(FilterTest, include_nested) { 1826 struct sock_fprog actual; 1827 std::string policy = "@include ./test/nested.policy\n"; 1828 1829 FILE* policy_file = write_policy_to_pipe(policy); 1830 ASSERT_NE(policy_file, nullptr); 1831 1832 /* Ensure the policy file exists. */ 1833 FILE* included_file = fopen(source_path("test/nested.policy").c_str(), "re"); 1834 ASSERT_NE(included_file, nullptr); 1835 fclose(included_file); 1836 1837 int res = test_compile_filter("policy", policy_file, &actual); 1838 fclose(policy_file); 1839 1840 ASSERT_NE(res, 0); 1841 } 1842 1843 #endif // !__ANDROID__ 1844 1845 TEST(FilterTest, error_cleanup_leak) { 1846 struct sock_fprog actual; 1847 std::string policy = 1848 "read:&&\n" 1849 "read:&&"; 1850 1851 FILE* policy_file = write_policy_to_pipe(policy); 1852 ASSERT_NE(policy_file, nullptr); 1853 int res = test_compile_filter("policy", policy_file, &actual); 1854 fclose(policy_file); 1855 1856 /* 1857 * Policy is malformed, but process should not leak. 1858 */ 1859 ASSERT_EQ(res, -1); 1860 } 1861