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