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