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