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