blob: 95b38f499c2f0e2efd34266342ee70a2533a3c44 [file] [log] [blame]
Mike Frysinger50e31fa2018-01-19 18:59:49 -05001/* 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 */
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04007
8#include <asm/unistd.h>
9#include <errno.h>
10#include <fcntl.h> /* For O_WRONLY. */
11
12#include <gtest/gtest.h>
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -040013#include <string>
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -040014
15#include "bpf.h"
16#include "syscall_filter.h"
17#include "syscall_filter_unittest_macros.h"
18#include "util.h"
19
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040020namespace {
21
Mike Frysingerdd5a8842018-08-15 15:57:44 -040022// 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
26std::string source_path(std::string file) {
27 std::string srcdir = getenv("SRC") ? : ".";
28 return srcdir + "/" + file;
29}
30
31#endif
32
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040033// Simple C++ -> C wrappers to simplify test code.
34
35enum ret_trap {
36 USE_RET_KILL = 0,
37 USE_RET_TRAP = 1,
38};
39
40enum use_logging {
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040041 NO_LOGGING = 0,
42 USE_SIGSYS_LOGGING = 1,
43 USE_RET_LOG_LOGGING = 2,
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040044};
45
46int test_compile_filter(
47 std::string filename,
48 FILE* policy_file,
49 struct sock_fprog* prog,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040050 enum block_action action = ACTION_RET_KILL,
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040051 enum use_logging allow_logging = NO_LOGGING) {
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040052 struct filter_options filteropts {
53 .action = action,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040054 .allow_logging = allow_logging != NO_LOGGING,
55 .allow_syscalls_for_logging = allow_logging == USE_SIGSYS_LOGGING,
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040056 };
57 return compile_filter(filename.c_str(), policy_file, prog, &filteropts);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040058}
59
60int test_compile_file(
61 std::string filename,
62 FILE* policy_file,
63 struct filter_block* head,
64 struct filter_block** arg_blocks,
65 struct bpf_labels* labels,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040066 enum block_action action = ACTION_RET_KILL,
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040067 enum use_logging allow_logging = NO_LOGGING,
68 unsigned int include_level = 0) {
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040069 struct filter_options filteropts {
70 .action = action,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040071 .allow_logging = allow_logging != NO_LOGGING,
72 .allow_syscalls_for_logging = allow_logging == USE_SIGSYS_LOGGING,
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040073 };
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040074 return compile_file(filename.c_str(), policy_file, head, arg_blocks, labels,
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040075 &filteropts, include_level);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040076}
77
78struct filter_block* test_compile_policy_line(
79 struct parser_state* state,
80 int nr,
81 std::string policy_line,
82 unsigned int label_id,
83 struct bpf_labels* labels,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040084 enum block_action action = ACTION_RET_KILL) {
85 return compile_policy_line(state, nr, policy_line.c_str(), label_id,
86 labels, action);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040087}
88
89} // namespace
90
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -040091TEST(util, parse_constant_unsigned) {
92 char *end;
93 long int c = 0;
94 std::string constant;
95
96#if defined(BITS32)
97 constant = "0x80000000";
Luis Hector Chavez466f2312018-10-31 10:44:43 -070098 c = parse_constant(const_cast<char*>(constant.data()), &end);
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -040099 EXPECT_EQ(0x80000000U, static_cast<unsigned long int>(c));
100
101#elif defined(BITS64)
102 constant = "0x8000000000000000";
Luis Hector Chavez466f2312018-10-31 10:44:43 -0700103 c = parse_constant(const_cast<char*>(constant.data()), &end);
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -0400104 EXPECT_EQ(0x8000000000000000UL, static_cast<unsigned long int>(c));
105#endif
106}
107
108TEST(util, parse_constant_unsigned_toobig) {
109 char *end;
110 long int c = 0;
111 std::string constant;
112
113#if defined(BITS32)
114 constant = "0x100000000"; // Too big for 32-bit unsigned long int.
Luis Hector Chavez466f2312018-10-31 10:44:43 -0700115 c = parse_constant(const_cast<char*>(constant.data()), &end);
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -0400116 // Error case should return 0.
117 EXPECT_EQ(0, c);
118
119#elif defined(BITS64)
120 constant = "0x10000000000000000";
Luis Hector Chavez466f2312018-10-31 10:44:43 -0700121 c = parse_constant(const_cast<char*>(constant.data()), &end);
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -0400122 // Error case should return 0.
123 EXPECT_EQ(0, c);
124#endif
125}
126
127TEST(util, parse_constant_signed) {
128 char *end;
129 long int c = 0;
130 std::string constant = "-1";
Luis Hector Chavez466f2312018-10-31 10:44:43 -0700131 c = parse_constant(const_cast<char*>(constant.data()), &end);
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -0400132 EXPECT_EQ(-1, c);
133}
134
135TEST(util, parse_constant_signed_toonegative) {
136 char *end;
137 long int c = 0;
138 std::string constant;
139
140#if defined(BITS32)
141 constant = "-0x80000001";
Luis Hector Chavez466f2312018-10-31 10:44:43 -0700142 c = parse_constant(const_cast<char*>(constant.data()), &end);
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -0400143 // Error case should return 0.
144 EXPECT_EQ(0, c);
145
146#elif defined(BITS64)
147 constant = "-0x8000000000000001";
Luis Hector Chavez466f2312018-10-31 10:44:43 -0700148 c = parse_constant(const_cast<char*>(constant.data()), &end);
Jorge Lucangeli Obes07459372016-10-19 15:33:31 -0400149 // Error case should return 0.
150 EXPECT_EQ(0, c);
151#endif
152}
153
Luis Hector Chavez466f2312018-10-31 10:44:43 -0700154TEST(util, parse_constant_complements) {
155 char* end;
156 long int c = 0;
157 std::string constant;
158
159#if defined(BITS32)
160 constant = "~0x005AF0FF|~0xFFA50FFF";
161 c = parse_constant(const_cast<char*>(constant.data()), &end);
162 EXPECT_EQ(c, 0xFFFFFF00);
163 constant = "0x0F|~(0x005AF000|0x00A50FFF)|0xF0";
164 c = parse_constant(const_cast<char*>(constant.data()), &end);
165 EXPECT_EQ(c, 0xFF0000FF);
166
167#elif defined(BITS64)
168 constant = "~0x00005A5AF0F0FFFF|~0xFFFFA5A50F0FFFFF";
169 c = parse_constant(const_cast<char*>(constant.data()), &end);
170 EXPECT_EQ(c, 0xFFFFFFFFFFFF0000UL);
171 constant = "0x00FF|~(0x00005A5AF0F00000|0x0000A5A50F0FFFFF)|0xFF00";
172 c = parse_constant(const_cast<char*>(constant.data()), &end);
173 EXPECT_EQ(c, 0xFFFF00000000FFFFUL);
174#endif
175}
176
177TEST(util, parse_parenthesized_expresions) {
178 char* end;
179
180 const std::vector<const char*> bad_expressions = {
181 "(1", "1)", "(1)1", "|(1)", "(1)|", "()",
182 "(", "((", "(()", "(()1", "1(0)",
183 };
184 for (const auto* expression : bad_expressions) {
185 std::string mutable_expression = expression;
186 long int c =
187 parse_constant(const_cast<char*>(mutable_expression.data()), &end);
188 EXPECT_EQ(reinterpret_cast<const void*>(end),
189 reinterpret_cast<const void*>(mutable_expression.data()));
190 // Error case should return 0.
191 EXPECT_EQ(c, 0) << "For expression: \"" << expression << "\"";
192 }
193
194 const std::vector<const char*> good_expressions = {
195 "(3)", "(1)|2", "1|(2)", "(1)|(2)", "((3))", "0|(1|2)", "(0|1|2)",
196 };
197 for (const auto* expression : good_expressions) {
198 std::string mutable_expression = expression;
199 long int c =
200 parse_constant(const_cast<char*>(mutable_expression.data()), &end);
201 EXPECT_EQ(c, 3) << "For expression: \"" << expression << "\"";
202 }
203}
204
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400205/* Test that setting one BPF instruction works. */
206TEST(bpf, set_bpf_instr) {
207 struct sock_filter instr;
208 unsigned char code = BPF_LD + BPF_W + BPF_ABS;
209 unsigned int k = 4;
210 unsigned char jt = 1, jf = 2;
211
212 size_t len = set_bpf_instr(&instr, code, k, jt, jf);
213
214 EXPECT_EQ(len, 1U);
215 EXPECT_EQ_BLOCK(&instr, code, k, jt, jf);
216}
217
218TEST(bpf, bpf_load_arg) {
219 struct sock_filter load_arg[BPF_LOAD_ARG_LEN];
Jorge Lucangeli Obes9bd316b2017-01-26 17:21:16 -0500220 const int argidx = 1;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400221 size_t len = bpf_load_arg(load_arg, argidx);
222
223 EXPECT_EQ(len, BPF_LOAD_ARG_LEN);
224
225#if defined(BITS32)
226 EXPECT_EQ_STMT(&load_arg[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
227#elif defined(BITS64)
228 EXPECT_EQ_STMT(&load_arg[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
229 EXPECT_EQ_STMT(&load_arg[1], BPF_ST, 0);
230 EXPECT_EQ_STMT(&load_arg[2], BPF_LD + BPF_W + BPF_ABS, HI_ARG(argidx));
231 EXPECT_EQ_STMT(&load_arg[3], BPF_ST, 1);
232#endif
233}
234
235TEST(bpf, bpf_comp_jeq) {
236 struct sock_filter comp_jeq[BPF_COMP_LEN];
237 unsigned long c = 1;
238 unsigned char jt = 1;
239 unsigned char jf = 2;
240
241 size_t len = bpf_comp_jeq(comp_jeq, c, jt, jf);
242
243 EXPECT_EQ(len, BPF_COMP_LEN);
244
245#if defined(BITS32)
246 EXPECT_EQ_BLOCK(&comp_jeq[0], BPF_JMP + BPF_JEQ + BPF_K, c, jt, jf);
247#elif defined(BITS64)
248 EXPECT_EQ_BLOCK(&comp_jeq[0], BPF_JMP + BPF_JEQ + BPF_K, 0, 0, jf + 2);
249 EXPECT_EQ_STMT(&comp_jeq[1], BPF_LD + BPF_MEM, 0);
250 EXPECT_EQ_BLOCK(&comp_jeq[2], BPF_JMP + BPF_JEQ + BPF_K, c, jt, jf);
251#endif
252}
253
254TEST(bpf, bpf_comp_jset) {
255 struct sock_filter comp_jset[BPF_COMP_LEN];
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400256 unsigned long mask = (1UL << (sizeof(unsigned long) * 8 - 1)) | O_WRONLY;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400257 unsigned char jt = 1;
258 unsigned char jf = 2;
259
260 size_t len = bpf_comp_jset(comp_jset, mask, jt, jf);
261
262 EXPECT_EQ(len, BPF_COMP_LEN);
263
264#if defined(BITS32)
265 EXPECT_EQ_BLOCK(&comp_jset[0], BPF_JMP + BPF_JSET + BPF_K, mask, jt, jf);
266#elif defined(BITS64)
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400267 EXPECT_EQ_BLOCK(
268 &comp_jset[0], BPF_JMP + BPF_JSET + BPF_K, 0x80000000, jt + 2, 0);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400269 EXPECT_EQ_STMT(&comp_jset[1], BPF_LD + BPF_MEM, 0);
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400270 EXPECT_EQ_BLOCK(&comp_jset[2], BPF_JMP + BPF_JSET + BPF_K, O_WRONLY, jt, jf);
271#endif
272}
273
274TEST(bpf, bpf_comp_jin) {
275 struct sock_filter comp_jin[BPF_COMP_LEN];
276 unsigned long mask = (1UL << (sizeof(unsigned long) * 8 - 1)) | O_WRONLY;
277 unsigned char jt = 10;
278 unsigned char jf = 20;
279
280 size_t len = bpf_comp_jin(comp_jin, mask, jt, jf);
281
282 EXPECT_EQ(len, BPF_COMP_LEN);
283
284#if defined(BITS32)
285 EXPECT_EQ_BLOCK(&comp_jin[0], BPF_JMP + BPF_JSET + BPF_K, ~mask, jf, jt);
286#elif defined(BITS64)
287 EXPECT_EQ_BLOCK(
288 &comp_jin[0], BPF_JMP + BPF_JSET + BPF_K, 0x7FFFFFFF, jf + 2, 0);
289 EXPECT_EQ_STMT(&comp_jin[1], BPF_LD + BPF_MEM, 0);
290 EXPECT_EQ_BLOCK(&comp_jin[2], BPF_JMP + BPF_JSET + BPF_K, ~O_WRONLY, jf, jt);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400291#endif
292}
293
294TEST(bpf, bpf_arg_comp) {
295 struct sock_filter *arg_comp;
296 int op = EQ;
Jorge Lucangeli Obes9bd316b2017-01-26 17:21:16 -0500297 const int argidx = 1;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400298 unsigned long c = 3;
299 unsigned int label_id = 0;
300
301 size_t len = bpf_arg_comp(&arg_comp, op, argidx, c, label_id);
302
303 EXPECT_EQ(len, BPF_ARG_COMP_LEN + 1);
304
305#if defined(BITS32)
306 EXPECT_EQ_STMT(&arg_comp[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
307 EXPECT_EQ_BLOCK(&arg_comp[1], BPF_JMP + BPF_JEQ + BPF_K, c, 1, 0);
308 EXPECT_JUMP_LBL(&arg_comp[2]);
309#elif defined(BITS64)
310 EXPECT_EQ_STMT(&arg_comp[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
311 EXPECT_EQ_STMT(&arg_comp[1], BPF_ST, 0);
312 EXPECT_EQ_STMT(&arg_comp[2], BPF_LD + BPF_W + BPF_ABS, HI_ARG(argidx));
313 EXPECT_EQ_STMT(&arg_comp[3], BPF_ST, 1);
314
315 EXPECT_EQ_BLOCK(&arg_comp[4], BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 2);
316 EXPECT_EQ_STMT(&arg_comp[5], BPF_LD + BPF_MEM, 0);
317 EXPECT_EQ_BLOCK(&arg_comp[6], BPF_JMP + BPF_JEQ + BPF_K, c, 1, 0);
318 EXPECT_JUMP_LBL(&arg_comp[7]);
319#endif
320 free(arg_comp);
321}
322
323TEST(bpf, bpf_validate_arch) {
324 struct sock_filter validate_arch[ARCH_VALIDATION_LEN];
325
326 size_t len = bpf_validate_arch(validate_arch);
327
328 EXPECT_EQ(len, ARCH_VALIDATION_LEN);
329 EXPECT_ARCH_VALIDATION(validate_arch);
330}
331
332TEST(bpf, bpf_allow_syscall) {
333 struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN];
334 int nr = 1;
335
336 size_t len = bpf_allow_syscall(allow_syscall, nr);
337
338 EXPECT_EQ(len, ALLOW_SYSCALL_LEN);
339 EXPECT_ALLOW_SYSCALL(allow_syscall, nr);
340}
341
342TEST(bpf, bpf_allow_syscall_args) {
343 struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN];
344 int nr = 1;
345 unsigned int id = 1024;
346
347 size_t len = bpf_allow_syscall_args(allow_syscall, nr, id);
348
349 EXPECT_EQ(len, ALLOW_SYSCALL_LEN);
350 EXPECT_ALLOW_SYSCALL_ARGS(allow_syscall, nr, id, JUMP_JT, JUMP_JF);
351}
352
Jorge Lucangeli Obes8cc9d4a2016-10-03 10:00:57 -0400353class BpfLabelTest : public ::testing::Test {
354 protected:
Jorge Lucangeli Obes9bd316b2017-01-26 17:21:16 -0500355 virtual void SetUp() { labels_.count = 0; }
Jorge Lucangeli Obes8cc9d4a2016-10-03 10:00:57 -0400356 virtual void TearDown() { free_label_strings(&labels_); }
357 struct bpf_labels labels_;
358};
359
360TEST_F(BpfLabelTest, zero_length_filter) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400361 int res = bpf_resolve_jumps(&labels_, nullptr, 0);
Jorge Lucangeli Obes8cc9d4a2016-10-03 10:00:57 -0400362
363 EXPECT_EQ(res, 0);
364 EXPECT_EQ(labels_.count, 0U);
365}
366
367TEST_F(BpfLabelTest, single_label) {
368 struct sock_filter test_label[1];
369
370 int id = bpf_label_id(&labels_, "test");
371 set_bpf_lbl(test_label, id);
372 int res = bpf_resolve_jumps(&labels_, test_label, 1);
373
374 EXPECT_EQ(res, 0);
375 EXPECT_EQ(labels_.count, 1U);
376}
377
378TEST_F(BpfLabelTest, repeated_label) {
379 struct sock_filter test_label[2];
380
381 int id = bpf_label_id(&labels_, "test");
382 set_bpf_lbl(&test_label[0], id);
383 set_bpf_lbl(&test_label[1], id);
384 int res = bpf_resolve_jumps(&labels_, test_label, 2);
385
386 EXPECT_EQ(res, -1);
387}
388
389TEST_F(BpfLabelTest, jump_with_no_label) {
390 struct sock_filter test_jump[1];
391
392 set_bpf_jump_lbl(test_jump, 14831);
393 int res = bpf_resolve_jumps(&labels_, test_jump, 1);
394
395 EXPECT_EQ(res, -1);
396}
397
398TEST_F(BpfLabelTest, jump_to_valid_label) {
399 struct sock_filter test_jump[2];
400
401 int id = bpf_label_id(&labels_, "test");
402 set_bpf_jump_lbl(&test_jump[0], id);
403 set_bpf_lbl(&test_jump[1], id);
404
405 int res = bpf_resolve_jumps(&labels_, test_jump, 2);
406 EXPECT_EQ(res, 0);
407 EXPECT_EQ(labels_.count, 1U);
408}
409
410TEST_F(BpfLabelTest, jump_to_invalid_label) {
411 struct sock_filter test_jump[2];
412
413 int id = bpf_label_id(&labels_, "test");
414 set_bpf_jump_lbl(&test_jump[0], id + 1);
415 set_bpf_lbl(&test_jump[1], id);
416
417 int res = bpf_resolve_jumps(&labels_, test_jump, 2);
418 EXPECT_EQ(res, -1);
419}
420
421TEST_F(BpfLabelTest, jump_to_unresolved_label) {
422 struct sock_filter test_jump[2];
423
424 int id = bpf_label_id(&labels_, "test");
425 /* Notice the order of the instructions is reversed. */
426 set_bpf_lbl(&test_jump[0], id);
427 set_bpf_jump_lbl(&test_jump[1], id);
428
429 int res = bpf_resolve_jumps(&labels_, test_jump, 2);
430 EXPECT_EQ(res, -1);
431}
432
433TEST_F(BpfLabelTest, too_many_labels) {
434 unsigned int i;
435 char label[20];
436
437 for (i = 0; i < BPF_LABELS_MAX; i++) {
438 snprintf(label, 20, "test%u", i);
439 (void) bpf_label_id(&labels_, label);
440 }
441 int id = bpf_label_id(&labels_, "test");
442
443 /* Insertion failed... */
444 EXPECT_EQ(id, -1);
445 /* ... because the label lookup table is full. */
446 EXPECT_EQ(labels_.count, BPF_LABELS_MAX);
447}
448
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400449class ArgFilterTest : public ::testing::Test {
450 protected:
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700451 virtual void SetUp() {
452 labels_.count = 0;
453 state_.filename = "policy";
454 state_.line_number = 1;
455 }
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400456 virtual void TearDown() { free_label_strings(&labels_); }
457 struct bpf_labels labels_;
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700458 int nr_ = 1;
459 unsigned int id_ = 0;
460 struct parser_state state_;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400461};
462
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400463TEST_F(ArgFilterTest, empty_atom) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400464 std::string fragment = "";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400465
466 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400467 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400468 ASSERT_EQ(block, nullptr);
469}
470
471TEST_F(ArgFilterTest, whitespace_atom) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400472 std::string fragment = "\t ";
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400473
474 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400475 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400476 ASSERT_EQ(block, nullptr);
477}
478
479TEST_F(ArgFilterTest, no_comparison) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400480 std::string fragment = "arg0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400481
482 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400483 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400484 ASSERT_EQ(block, nullptr);
485}
486
487TEST_F(ArgFilterTest, no_constant) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400488 std::string fragment = "arg0 ==";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400489
490 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400491 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400492 ASSERT_EQ(block, nullptr);
493}
494
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400495TEST_F(ArgFilterTest, arg0_equals) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400496 std::string fragment = "arg0 == 0";
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700497
498 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400499 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400500
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400501 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400502 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
503 EXPECT_EQ(block->total_len, exp_total_len);
504
505 /* First block is a label. */
506 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400507 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400508 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400509 EXPECT_LBL(curr_block->instrs);
510
511 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400512 curr_block = curr_block->next;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400513 EXPECT_COMP(curr_block);
514
515 /* Third block is a jump and a label (end of AND group). */
516 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400517 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400518 EXPECT_GROUP_END(curr_block);
519
520 /* Fourth block is SECCOMP_RET_KILL. */
521 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400522 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400523 EXPECT_KILL(curr_block);
524
525 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
526 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400527 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400528 EXPECT_ALLOW(curr_block);
529
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400530 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400531
532 free_block_list(block);
533}
534
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -0400535TEST_F(ArgFilterTest, arg0_equals_trap) {
536 std::string fragment = "arg0 == 0";
537
538 struct filter_block* block = test_compile_policy_line(
539 &state_, nr_, fragment, id_, &labels_, ACTION_RET_TRAP);
540
541 ASSERT_NE(block, nullptr);
542 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
543 EXPECT_EQ(block->total_len, exp_total_len);
544
545 /* First block is a label. */
546 struct filter_block* curr_block = block;
547 ASSERT_NE(curr_block, nullptr);
548 EXPECT_EQ(curr_block->len, 1U);
549 EXPECT_LBL(curr_block->instrs);
550
551 /* Second block is a comparison. */
552 curr_block = curr_block->next;
553 EXPECT_COMP(curr_block);
554
555 /* Third block is a jump and a label (end of AND group). */
556 curr_block = curr_block->next;
557 ASSERT_NE(curr_block, nullptr);
558 EXPECT_GROUP_END(curr_block);
559
560 /* Fourth block is SECCOMP_RET_TRAP. */
561 curr_block = curr_block->next;
562 ASSERT_NE(curr_block, nullptr);
563 EXPECT_TRAP(curr_block);
564
565 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
566 curr_block = curr_block->next;
567 ASSERT_NE(curr_block, nullptr);
568 EXPECT_ALLOW(curr_block);
569
570 EXPECT_EQ(curr_block->next, nullptr);
571
572 free_block_list(block);
573}
574
575TEST_F(ArgFilterTest, arg0_equals_log) {
576 std::string fragment = "arg0 == 0";
577
578 struct filter_block* block = test_compile_policy_line(
579 &state_, nr_, fragment, id_, &labels_, ACTION_RET_LOG);
580
581 ASSERT_NE(block, nullptr);
582 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
583 EXPECT_EQ(block->total_len, exp_total_len);
584
585 /* First block is a label. */
586 struct filter_block* curr_block = block;
587 ASSERT_NE(curr_block, nullptr);
588 EXPECT_EQ(curr_block->len, 1U);
589 EXPECT_LBL(curr_block->instrs);
590
591 /* Second block is a comparison. */
592 curr_block = curr_block->next;
593 EXPECT_COMP(curr_block);
594
595 /* Third block is a jump and a label (end of AND group). */
596 curr_block = curr_block->next;
597 ASSERT_NE(curr_block, nullptr);
598 EXPECT_GROUP_END(curr_block);
599
600 /* Fourth block is SECCOMP_RET_LOG. */
601 curr_block = curr_block->next;
602 ASSERT_NE(curr_block, nullptr);
603 EXPECT_LOG(curr_block);
604
605 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
606 curr_block = curr_block->next;
607 ASSERT_NE(curr_block, nullptr);
608 EXPECT_ALLOW(curr_block);
609
610 EXPECT_EQ(curr_block->next, nullptr);
611
612 free_block_list(block);
613}
614
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700615TEST_F(ArgFilterTest, arg0_short_gt_ge_comparisons) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400616 for (std::string fragment :
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700617 {"arg1 < 0xff", "arg1 <= 0xff", "arg1 > 0xff", "arg1 >= 0xff"}) {
618 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400619 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700620
621 ASSERT_NE(block, nullptr);
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700622 size_t exp_total_len = 1 + (BPF_ARG_SHORT_GT_GE_COMP_LEN + 1) + 2 + 1 + 2;
623 EXPECT_EQ(block->total_len, exp_total_len);
624
625 // First block is a label.
626 struct filter_block* curr_block = block;
627 ASSERT_NE(curr_block, nullptr);
628 EXPECT_EQ(curr_block->len, 1U);
629 EXPECT_LBL(curr_block->instrs);
630
631 // Second block is a short gt/ge comparison.
632 curr_block = curr_block->next;
633 EXPECT_SHORT_GT_GE_COMP(curr_block);
634
635 // Third block is a jump and a label (end of AND group).
636 curr_block = curr_block->next;
637 ASSERT_NE(curr_block, nullptr);
638 EXPECT_GROUP_END(curr_block);
639
640 // Fourth block is SECCOMP_RET_KILL.
641 curr_block = curr_block->next;
642 ASSERT_NE(curr_block, nullptr);
643 EXPECT_KILL(curr_block);
644
645 // Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW.
646 curr_block = curr_block->next;
647 ASSERT_NE(curr_block, nullptr);
648 EXPECT_ALLOW(curr_block);
649
650 EXPECT_EQ(curr_block->next, nullptr);
651
652 free_block_list(block);
653 }
654}
655
656#if defined(BITS64)
657TEST_F(ArgFilterTest, arg0_long_gt_ge_comparisons) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400658 for (std::string fragment :
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700659 {"arg1 < 0xbadc0ffee0ddf00d", "arg1 <= 0xbadc0ffee0ddf00d",
660 "arg1 > 0xbadc0ffee0ddf00d", "arg1 >= 0xbadc0ffee0ddf00d"}) {
661 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400662 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700663
664 ASSERT_NE(block, nullptr);
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700665 size_t exp_total_len = 1 + (BPF_ARG_GT_GE_COMP_LEN + 1) + 2 + 1 + 2;
666 EXPECT_EQ(block->total_len, exp_total_len);
667
668 // First block is a label.
669 struct filter_block* curr_block = block;
670 ASSERT_NE(curr_block, nullptr);
671 EXPECT_EQ(curr_block->len, 1U);
672 EXPECT_LBL(curr_block->instrs);
673
674 // Second block is a gt/ge comparison.
675 curr_block = curr_block->next;
676 EXPECT_GT_GE_COMP(curr_block);
677
678 // Third block is a jump and a label (end of AND group).
679 curr_block = curr_block->next;
680 ASSERT_NE(curr_block, nullptr);
681 EXPECT_GROUP_END(curr_block);
682
683 // Fourth block is SECCOMP_RET_KILL.
684 curr_block = curr_block->next;
685 ASSERT_NE(curr_block, nullptr);
686 EXPECT_KILL(curr_block);
687
688 // Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW.
689 curr_block = curr_block->next;
690 ASSERT_NE(curr_block, nullptr);
691 EXPECT_ALLOW(curr_block);
692
693 EXPECT_EQ(curr_block->next, nullptr);
694
695 free_block_list(block);
696 }
697}
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700698#endif
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700699
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400700TEST_F(ArgFilterTest, arg0_mask) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400701 std::string fragment = "arg1 & O_RDWR";
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700702
703 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400704 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400705
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400706 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400707 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
708 EXPECT_EQ(block->total_len, exp_total_len);
709
710 /* First block is a label. */
711 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400712 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400713 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400714 EXPECT_LBL(curr_block->instrs);
715
716 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400717 curr_block = curr_block->next;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400718 EXPECT_COMP(curr_block);
719
720 /* Third block is a jump and a label (end of AND group). */
721 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400722 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400723 EXPECT_GROUP_END(curr_block);
724
725 /* Fourth block is SECCOMP_RET_KILL. */
726 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400727 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400728 EXPECT_KILL(curr_block);
729
730 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
731 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400732 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400733 EXPECT_ALLOW(curr_block);
734
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400735 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400736
737 free_block_list(block);
738}
739
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400740TEST_F(ArgFilterTest, arg0_flag_set_inclusion) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400741 std::string fragment = "arg0 in O_RDONLY|O_CREAT";
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700742
743 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400744 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400745
746 ASSERT_NE(block, nullptr);
747 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
748 EXPECT_EQ(block->total_len, exp_total_len);
749
750 /* First block is a label. */
751 struct filter_block *curr_block = block;
752 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400753 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400754 EXPECT_LBL(curr_block->instrs);
755
756 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400757 curr_block = curr_block->next;
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400758 ASSERT_NE(curr_block, nullptr);
759 EXPECT_COMP(curr_block);
760
761 /* Third block is a jump and a label (end of AND group). */
762 curr_block = curr_block->next;
763 ASSERT_NE(curr_block, nullptr);
764 EXPECT_GROUP_END(curr_block);
765
766 /* Fourth block is SECCOMP_RET_KILL. */
767 curr_block = curr_block->next;
768 ASSERT_NE(curr_block, nullptr);
769 EXPECT_KILL(curr_block);
770
771 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
772 curr_block = curr_block->next;
773 ASSERT_NE(curr_block, nullptr);
774 EXPECT_ALLOW(curr_block);
775
776 EXPECT_EQ(curr_block->next, nullptr);
777
778 free_block_list(block);
779}
780
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400781TEST_F(ArgFilterTest, arg0_eq_mask) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400782 std::string fragment = "arg1 == O_WRONLY|O_CREAT";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400783
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700784 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400785 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400786
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400787 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400788 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
789 EXPECT_EQ(block->total_len, exp_total_len);
790
791 /* First block is a label. */
792 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400793 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400794 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400795 EXPECT_LBL(curr_block->instrs);
796
797 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400798 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400799 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400800 EXPECT_COMP(curr_block);
801 EXPECT_EQ(curr_block->instrs[BPF_ARG_COMP_LEN - 1].k,
802 (unsigned int)(O_WRONLY | O_CREAT));
803
804 /* Third block is a jump and a label (end of AND group). */
805 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400806 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400807 EXPECT_GROUP_END(curr_block);
808
809 /* Fourth block is SECCOMP_RET_KILL. */
810 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400811 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400812 EXPECT_KILL(curr_block);
813
814 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
815 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400816 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400817 EXPECT_ALLOW(curr_block);
818
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400819 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400820
821 free_block_list(block);
822}
823
824TEST_F(ArgFilterTest, and_or) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400825 std::string fragment = "arg0 == 0 && arg1 == 0 || arg0 == 1";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400826
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700827 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400828 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400829 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400830 size_t exp_total_len = 1 + 3 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2;
831 EXPECT_EQ(block->total_len, exp_total_len);
832
833 /* First block is a label. */
834 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400835 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400836 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400837 EXPECT_LBL(curr_block->instrs);
838
839 /* Second block is a comparison ("arg0 == 0"). */
840 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400841 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400842 EXPECT_COMP(curr_block);
843
844 /* Third block is a comparison ("arg1 == 0"). */
845 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400846 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400847 EXPECT_COMP(curr_block);
848
849 /* Fourth block is a jump and a label (end of AND group). */
850 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400851 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400852 EXPECT_GROUP_END(curr_block);
853
854 /* Fifth block is a comparison ("arg0 == 1"). */
855 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400856 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400857 EXPECT_COMP(curr_block);
858
859 /* Sixth block is a jump and a label (end of AND group). */
860 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400861 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400862 EXPECT_GROUP_END(curr_block);
863
864 /* Seventh block is SECCOMP_RET_KILL. */
865 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400866 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400867 EXPECT_KILL(curr_block);
868
869 /* Eigth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
870 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400871 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400872 EXPECT_ALLOW(curr_block);
873
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400874 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400875
876 free_block_list(block);
877}
878
879TEST_F(ArgFilterTest, ret_errno) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400880 std::string fragment = "arg0 == 0 || arg0 == 1; return 1";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400881
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700882 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400883 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400884 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400885 size_t exp_total_len = 1 + 2 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2;
886 EXPECT_EQ(block->total_len, exp_total_len);
887
888 /* First block is a label. */
889 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400890 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400891 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400892 EXPECT_LBL(curr_block->instrs);
893
894 /* Second block is a comparison ("arg0 == 0"). */
895 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400896 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400897 EXPECT_COMP(curr_block);
898
899 /* Third block is a jump and a label (end of AND group). */
900 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400901 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400902 EXPECT_GROUP_END(curr_block);
903
904 /* Fourth block is a comparison ("arg0 == 1"). */
905 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400906 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400907 EXPECT_COMP(curr_block);
908
909 /* Fifth block is a jump and a label (end of AND group). */
910 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400911 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400912 EXPECT_GROUP_END(curr_block);
913
914 /* Sixth block is SECCOMP_RET_ERRNO. */
915 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400916 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400917 EXPECT_EQ(curr_block->len, 1U);
918 EXPECT_EQ_STMT(curr_block->instrs,
919 BPF_RET + BPF_K,
920 SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA));
921
922 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
923 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400924 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400925 EXPECT_ALLOW(curr_block);
926
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400927 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400928
929 free_block_list(block);
930}
931
932TEST_F(ArgFilterTest, unconditional_errno) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400933 std::string fragment = "return 1";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400934
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700935 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400936 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400937 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400938 size_t exp_total_len = 2;
939 EXPECT_EQ(block->total_len, exp_total_len);
940
941 /* First block is a label. */
942 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400943 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400944 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400945 EXPECT_LBL(curr_block->instrs);
946
947 /* Second block is SECCOMP_RET_ERRNO. */
948 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400949 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400950 EXPECT_EQ(curr_block->len, 1U);
951 EXPECT_EQ_STMT(curr_block->instrs,
952 BPF_RET + BPF_K,
953 SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA));
954
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400955 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400956
957 free_block_list(block);
958}
959
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400960TEST_F(ArgFilterTest, invalid_arg_token) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400961 std::string fragment = "org0 == 0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400962
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700963 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400964 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400965 ASSERT_EQ(block, nullptr);
966}
967
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400968TEST_F(ArgFilterTest, invalid_arg_number) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400969 std::string fragment = "argnn == 0";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400970
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700971 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400972 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400973 ASSERT_EQ(block, nullptr);
974}
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400975
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400976TEST_F(ArgFilterTest, extra_chars_in_arg_token) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400977 std::string fragment = "arg0n == 0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400978
979 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400980 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400981 ASSERT_EQ(block, nullptr);
982}
983
984TEST_F(ArgFilterTest, invalid_operator) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400985 std::string fragment = "arg0 invalidop 0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400986
987 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400988 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400989 ASSERT_EQ(block, nullptr);
990}
991
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400992TEST_F(ArgFilterTest, invalid_constant) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400993 std::string fragment = "arg0 == INVALIDCONSTANT";
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400994
995 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400996 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400997 ASSERT_EQ(block, nullptr);
998}
999
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001000TEST_F(ArgFilterTest, extra_tokens) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001001 std::string fragment = "arg0 == 0 EXTRATOKEN";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001002
1003 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001004 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001005 ASSERT_EQ(block, nullptr);
1006}
1007
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -04001008TEST_F(ArgFilterTest, invalid_errno) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001009 std::string fragment = "arg0 == 0 && arg1 == 1; return errno";
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -04001010
Luis Hector Chavez7624e712017-08-28 19:30:59 -07001011 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001012 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -04001013 ASSERT_EQ(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001014}
1015
1016TEST_F(ArgFilterTest, log_no_ret_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001017 std::string fragment = "arg0 == 0";
Luis Hector Chavez7624e712017-08-28 19:30:59 -07001018
1019 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001020 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001021 ACTION_RET_TRAP);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001022
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001023 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001024 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
1025 EXPECT_EQ(block->total_len, exp_total_len);
1026
1027 /* First block is a label. */
1028 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001029 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001030 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001031 EXPECT_LBL(curr_block->instrs);
1032
1033 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001034 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001035 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001036 EXPECT_COMP(curr_block);
1037
1038 /* Third block is a jump and a label (end of AND group). */
1039 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001040 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001041 EXPECT_GROUP_END(curr_block);
1042
1043 /* Fourth block is SECCOMP_RET_TRAP, with no errno. */
1044 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001045 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001046 EXPECT_TRAP(curr_block);
1047
1048 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
1049 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001050 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001051 EXPECT_ALLOW(curr_block);
1052
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001053 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001054
1055 free_block_list(block);
1056}
1057
1058TEST_F(ArgFilterTest, log_bad_ret_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001059 std::string fragment = "arg0 == 0; return";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001060
Luis Hector Chavez7624e712017-08-28 19:30:59 -07001061 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001062 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001063 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001064 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
1065 EXPECT_EQ(block->total_len, exp_total_len);
1066
1067 /* First block is a label. */
1068 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001069 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001070 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001071 EXPECT_LBL(curr_block->instrs);
1072
1073 /* Second block is a comparison ("arg0 == 0"). */
1074 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001075 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001076 EXPECT_COMP(curr_block);
1077
1078 /* Third block is a jump and a label (end of AND group). */
1079 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001080 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001081 EXPECT_GROUP_END(curr_block);
1082
1083 /*
1084 * Sixth block is NOT SECCOMP_RET_ERRNO, it should be SECCOMP_RET_KILL.
1085 */
1086 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001087 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001088 EXPECT_KILL(curr_block);
1089
1090 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
1091 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001092 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001093 EXPECT_ALLOW(curr_block);
1094
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001095 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001096
1097 free_block_list(block);
1098}
1099
1100TEST_F(ArgFilterTest, no_log_bad_ret_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001101 std::string fragment = "arg0 == 0; return";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001102
Luis Hector Chavez7624e712017-08-28 19:30:59 -07001103 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001104 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001105 ACTION_RET_TRAP);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001106 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001107 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
1108 EXPECT_EQ(block->total_len, exp_total_len);
1109
1110 /* First block is a label. */
1111 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001112 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001113 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001114 EXPECT_LBL(curr_block->instrs);
1115
1116 /* Second block is a comparison ("arg0 == 0"). */
1117 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001118 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001119 EXPECT_COMP(curr_block);
1120
1121 /* Third block is a jump and a label (end of AND group). */
1122 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001123 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001124 EXPECT_GROUP_END(curr_block);
1125
1126 /*
1127 * Sixth block is *not* SECCOMP_RET_ERRNO, it should be
1128 * SECCOMP_RET_TRAP.
1129 */
1130 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001131 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001132 EXPECT_TRAP(curr_block);
1133
1134 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
1135 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001136 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001137 EXPECT_ALLOW(curr_block);
1138
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001139 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001140
1141 free_block_list(block);
1142}
1143
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001144namespace {
1145
1146FILE* write_policy_to_pipe(std::string policy) {
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001147 int pipefd[2];
1148 if (pipe(pipefd) == -1) {
1149 pwarn("pipe(pipefd) failed");
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001150 return nullptr;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001151 }
1152
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001153 size_t len = policy.length();
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001154 size_t i = 0;
1155 unsigned int attempts = 0;
1156 ssize_t ret;
1157 while (i < len) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001158 ret = write(pipefd[1], policy.c_str() + i, len - i);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001159 if (ret == -1) {
1160 close(pipefd[0]);
1161 close(pipefd[1]);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001162 return nullptr;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001163 }
1164
1165 /* If we write 0 bytes three times in a row, fail. */
1166 if (ret == 0) {
1167 if (++attempts >= 3) {
1168 close(pipefd[0]);
1169 close(pipefd[1]);
1170 warn("write() returned 0 three times in a row");
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001171 return nullptr;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001172 }
1173 continue;
1174 }
1175
1176 attempts = 0;
1177 i += (size_t)ret;
1178 }
1179
1180 close(pipefd[1]);
1181 return fdopen(pipefd[0], "r");
1182}
1183
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001184class FileTest : public ::testing::Test {
1185 protected:
1186 virtual void SetUp() {
1187 labels_.count = 0;
1188 head_ = new_filter_block();
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001189 arg_blocks_ = nullptr;
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001190 }
1191 virtual void TearDown() {
1192 free_label_strings(&labels_);
1193 free_block_list(head_);
1194 free_block_list(arg_blocks_);
1195 }
1196 struct bpf_labels labels_;
1197 struct filter_block *head_;
1198 struct filter_block *arg_blocks_;
1199};
1200
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001201} // namespace
1202
lhchavezd0b40702017-09-01 04:17:41 +00001203TEST_F(FileTest, malformed_policy) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001204 std::string policy =
lhchavezd0b40702017-09-01 04:17:41 +00001205 "malformed";
1206
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001207 FILE* policy_file = write_policy_to_pipe(policy);
lhchavezd0b40702017-09-01 04:17:41 +00001208 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001209 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1210 &labels_);
lhchavezd0b40702017-09-01 04:17:41 +00001211 fclose(policy_file);
1212
1213 /*
1214 * Policy is malformed, but process should not crash.
1215 */
1216 ASSERT_EQ(res, -1);
1217}
1218
lhchavezd38280c2017-09-01 14:00:05 +00001219TEST_F(FileTest, double_free_on_compile_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001220 std::string policy =
lhchavezd38280c2017-09-01 14:00:05 +00001221 "read:arg0 == 0\n"
1222 "write:0";
1223
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001224 FILE* policy_file = write_policy_to_pipe(policy);
lhchavezd38280c2017-09-01 14:00:05 +00001225 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001226 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1227 &labels_);
lhchavezd38280c2017-09-01 14:00:05 +00001228 fclose(policy_file);
1229
1230 /*
1231 * Policy is malformed, but process should not crash.
1232 */
1233 ASSERT_EQ(res, -1);
1234}
1235
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001236TEST_F(FileTest, invalid_return) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001237 std::string policy =
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001238 "read:arg0 == 0; ;";
1239
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001240 FILE* policy_file = write_policy_to_pipe(policy);
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001241 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001242 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1243 &labels_);
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001244 fclose(policy_file);
1245
1246 /*
1247 * Policy is malformed, but process should not crash.
1248 */
1249 ASSERT_EQ(res, -1);
1250}
1251
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001252TEST_F(FileTest, seccomp_mode1) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001253 std::string policy =
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001254 "read: 1\n"
1255 "write: 1\n"
1256 "rt_sigreturn: 1\n"
1257 "exit: 1\n";
1258
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001259 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001260 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001261 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1262 &labels_);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001263 fclose(policy_file);
1264
1265 /*
1266 * Checks return value and that the blocks only allow expected syscalls.
1267 */
1268 ASSERT_EQ(res, 0);
1269 struct filter_block *curr_block = head_;
1270 ASSERT_NE(curr_block, nullptr);
1271 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_read);
1272 curr_block = curr_block->next;
1273 ASSERT_NE(curr_block, nullptr);
1274 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_write);
1275 curr_block = curr_block->next;
1276 ASSERT_NE(curr_block, nullptr);
1277 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_rt_sigreturn);
1278 curr_block = curr_block->next;
1279 ASSERT_NE(curr_block, nullptr);
1280 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_exit);
1281
1282 EXPECT_EQ(curr_block->next, nullptr);
1283}
1284
1285TEST_F(FileTest, seccomp_read) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001286 std::string policy =
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001287 "read: arg0 == 0\n"
1288 "write: 1\n"
1289 "rt_sigreturn: 1\n"
1290 "exit: 1\n";
1291
1292 const int LABEL_ID = 0;
1293
Mike Frysingercdfb0cc2019-03-15 01:39:00 -04001294 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001295 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001296 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1297 &labels_);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001298 fclose(policy_file);
1299
1300 /*
1301 * Checks return value, that the blocks only allow expected syscalls, and that
1302 * labels between |head_| and |arg_blocks_| match.
1303 */
1304 ASSERT_EQ(res, 0);
1305 struct filter_block *curr_block = head_;
1306 ASSERT_NE(curr_block, nullptr);
1307 EXPECT_ALLOW_SYSCALL_ARGS(curr_block->instrs,
1308 __NR_read,
1309 LABEL_ID,
1310 JUMP_JT,
1311 JUMP_JF);
1312 curr_block = curr_block->next;
1313 ASSERT_NE(curr_block, nullptr);
1314 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_write);
1315 curr_block = curr_block->next;
1316 ASSERT_NE(curr_block, nullptr);
1317 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_rt_sigreturn);
1318 curr_block = curr_block->next;
1319 ASSERT_NE(curr_block, nullptr);
1320 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_exit);
1321
1322 ASSERT_NE(arg_blocks_, nullptr);
1323 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
1324 EXPECT_EQ(arg_blocks_->total_len, exp_total_len);
1325
1326 /* First block is a label. */
1327 curr_block = arg_blocks_;
1328 ASSERT_NE(curr_block, nullptr);
1329 EXPECT_EQ(curr_block->len, 1U);
1330 EXPECT_ACTUAL_LBL(curr_block->instrs, LABEL_ID);
1331
1332 /* Second block is a comparison. */
1333 curr_block = curr_block->next;
1334 EXPECT_COMP(curr_block);
1335
1336 /* Third block is a jump and a label (end of AND group). */
1337 curr_block = curr_block->next;
1338 ASSERT_NE(curr_block, nullptr);
1339 EXPECT_GROUP_END(curr_block);
1340
1341 /* Fourth block is SECCOMP_RET_KILL. */
1342 curr_block = curr_block->next;
1343 ASSERT_NE(curr_block, nullptr);
1344 EXPECT_KILL(curr_block);
1345
1346 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
1347 curr_block = curr_block->next;
1348 ASSERT_NE(curr_block, nullptr);
1349 EXPECT_ALLOW(curr_block);
1350
1351 EXPECT_EQ(curr_block->next, nullptr);
1352}
1353
Mike Frysinger29c72342019-03-15 01:39:31 -04001354TEST_F(FileTest, multiline) {
1355 std::string policy =
1356 "read:\\\n1\n"
Mike Frysingere4c69652019-06-26 04:33:17 -04001357 "openat:arg0 \\\nin\\\n \\\n5";
Mike Frysinger29c72342019-03-15 01:39:31 -04001358
1359 const int LABEL_ID = 0;
1360
1361 FILE* policy_file = write_policy_to_pipe(policy);
1362 ASSERT_NE(policy_file, nullptr);
1363 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1364 &labels_);
1365 fclose(policy_file);
1366
1367 /*
1368 * Policy should be valid.
1369 */
1370 ASSERT_EQ(res, 0);
1371
1372 /* First block is the read. */
1373 struct filter_block *curr_block = head_;
1374 ASSERT_NE(curr_block, nullptr);
1375 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_read);
1376
1377 /* Second block is the open. */
1378 curr_block = curr_block->next;
1379 ASSERT_NE(curr_block, nullptr);
1380 EXPECT_ALLOW_SYSCALL_ARGS(curr_block->instrs,
1381 __NR_openat,
1382 LABEL_ID,
1383 JUMP_JT,
1384 JUMP_JF);
1385
1386 EXPECT_EQ(curr_block->next, nullptr);
1387}
1388
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001389TEST(FilterTest, seccomp_mode1) {
1390 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001391 std::string policy =
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001392 "read: 1\n"
1393 "write: 1\n"
1394 "rt_sigreturn: 1\n"
1395 "exit: 1\n";
1396
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001397 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001398 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001399
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001400 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001401 fclose(policy_file);
1402
1403 /*
1404 * Checks return value, filter length, and that the filter
1405 * validates arch, loads syscall number, and
1406 * only allows expected syscalls.
1407 */
1408 ASSERT_EQ(res, 0);
1409 EXPECT_EQ(actual.len, 13);
1410 EXPECT_ARCH_VALIDATION(actual.filter);
1411 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1412 BPF_LD + BPF_W + BPF_ABS,
1413 syscall_nr);
1414 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read);
1415 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3, __NR_write);
1416 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1417 __NR_rt_sigreturn);
1418 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit);
1419 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9,
1420 BPF_RET + BPF_K,
1421 SECCOMP_RET_KILL);
1422
1423 free(actual.filter);
1424}
1425
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001426TEST(FilterTest, seccomp_mode1_trap) {
1427 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001428 std::string policy =
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001429 "read: 1\n"
1430 "write: 1\n"
1431 "rt_sigreturn: 1\n"
1432 "exit: 1\n";
1433
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001434 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001435 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001436
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001437 int res =
1438 test_compile_filter("policy", policy_file, &actual, ACTION_RET_TRAP);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001439 fclose(policy_file);
1440
1441 /*
1442 * Checks return value, filter length, and that the filter
1443 * validates arch, loads syscall number, and
1444 * only allows expected syscalls.
1445 */
1446 ASSERT_EQ(res, 0);
1447 EXPECT_EQ(actual.len, 13);
1448 EXPECT_ARCH_VALIDATION(actual.filter);
1449 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1450 BPF_LD+BPF_W+BPF_ABS, syscall_nr);
1451 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1,
1452 __NR_read);
1453 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3,
1454 __NR_write);
1455 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1456 __NR_rt_sigreturn);
1457 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
1458 __NR_exit);
1459 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
1460 SECCOMP_RET_TRAP);
1461
1462 free(actual.filter);
1463}
1464
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001465TEST(FilterTest, seccomp_mode1_log) {
1466 struct sock_fprog actual;
1467 std::string policy =
1468 "read: 1\n"
1469 "write: 1\n"
1470 "rt_sigreturn: 1\n"
1471 "exit: 1\n";
1472
1473 FILE* policy_file = write_policy_to_pipe(policy);
1474 ASSERT_NE(policy_file, nullptr);
1475
1476 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_LOG,
1477 USE_RET_LOG_LOGGING);
1478 fclose(policy_file);
1479
1480 /*
1481 * Checks return value, filter length, and that the filter
1482 * validates arch, loads syscall number, and
1483 * only allows expected syscalls.
1484 */
1485 ASSERT_EQ(res, 0);
1486 EXPECT_EQ(actual.len, 13);
1487 EXPECT_ARCH_VALIDATION(actual.filter);
1488 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1489 BPF_LD+BPF_W+BPF_ABS, syscall_nr);
1490 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1,
1491 __NR_read);
1492 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3,
1493 __NR_write);
1494 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1495 __NR_rt_sigreturn);
1496 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
1497 __NR_exit);
1498 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
1499 SECCOMP_RET_LOG);
1500
1501 free(actual.filter);
1502}
1503
1504TEST(FilterTest, seccomp_mode1_log_fails) {
1505 struct sock_fprog actual;
1506 std::string policy =
1507 "read: 1\n"
1508 "write: 1\n"
1509 "rt_sigreturn: 1\n"
1510 "exit: 1\n";
1511
1512 FILE* policy_file = write_policy_to_pipe(policy);
1513 ASSERT_NE(policy_file, nullptr);
1514
1515 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_LOG,
1516 NO_LOGGING);
1517 fclose(policy_file);
1518
1519 /*
1520 * ACTION_RET_LOG should never be used without allowing logging.
1521 */
1522 ASSERT_EQ(res, -1);
1523}
1524
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001525TEST(FilterTest, seccomp_read_write) {
1526 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001527 std::string policy =
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001528 "read: arg0 == 0\n"
1529 "write: arg0 == 1 || arg0 == 2\n"
1530 "rt_sigreturn: 1\n"
1531 "exit: 1\n";
1532
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001533 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001534 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001535
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001536 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001537 fclose(policy_file);
1538
1539 /*
1540 * Checks return value, filter length, and that the filter
1541 * validates arch, loads syscall number, and
1542 * only allows expected syscalls, jumping to correct arg filter
1543 * offsets.
1544 */
1545 ASSERT_EQ(res, 0);
1546 size_t exp_total_len = 27 + 3 * (BPF_ARG_COMP_LEN + 1);
1547 EXPECT_EQ(actual.len, exp_total_len);
1548
1549 EXPECT_ARCH_VALIDATION(actual.filter);
1550 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1551 BPF_LD + BPF_W + BPF_ABS,
1552 syscall_nr);
1553 EXPECT_ALLOW_SYSCALL_ARGS(
1554 actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read, 7, 0, 0);
1555 EXPECT_ALLOW_SYSCALL_ARGS(actual.filter + ARCH_VALIDATION_LEN + 3,
1556 __NR_write,
1557 12 + BPF_ARG_COMP_LEN,
1558 0,
1559 0);
1560 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1561 __NR_rt_sigreturn);
1562 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit);
1563 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9,
1564 BPF_RET + BPF_K,
1565 SECCOMP_RET_KILL);
1566
1567 free(actual.filter);
1568}
1569
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001570TEST(FilterTest, misplaced_whitespace) {
1571 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001572 std::string policy = "read :1\n";
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001573
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001574 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001575 ASSERT_NE(policy_file, nullptr);
1576
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001577 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001578 fclose(policy_file);
1579
1580 /* Checks return value and filter length. */
1581 ASSERT_EQ(res, 0);
1582 EXPECT_EQ(actual.len,
1583 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ + ALLOW_SYSCALL_LEN +
1584 1 /* ret kill */);
1585 free(actual.filter);
1586}
1587
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001588TEST(FilterTest, missing_atom) {
1589 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001590 std::string policy = "open:\n";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001591
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001592 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001593 ASSERT_NE(policy_file, nullptr);
1594
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001595 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001596 fclose(policy_file);
1597 ASSERT_NE(res, 0);
1598}
1599
1600TEST(FilterTest, whitespace_atom) {
1601 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001602 std::string policy = "open:\t \n";
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001603
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001604 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001605 ASSERT_NE(policy_file, nullptr);
1606
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001607 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001608 fclose(policy_file);
1609 ASSERT_NE(res, 0);
1610}
1611
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001612TEST(FilterTest, invalid_name) {
1613 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001614 std::string policy = "notasyscall: 1\n";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001615
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001616 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001617 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001618
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001619 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001620 fclose(policy_file);
1621 ASSERT_NE(res, 0);
1622}
1623
1624TEST(FilterTest, invalid_arg) {
1625 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001626 std::string policy = "open: argnn ==\n";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001627
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001628 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001629 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001630
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001631 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001632 fclose(policy_file);
1633 ASSERT_NE(res, 0);
1634}
1635
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001636TEST(FilterTest, invalid_tokens) {
1637 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001638 std::string policy = "read: arg0 == 1 |||| arg0 == 2\n";
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001639
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001640 FILE* policy_file = write_policy_to_pipe(policy);
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001641 ASSERT_NE(policy_file, nullptr);
1642
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001643 int res = test_compile_filter("policy", policy_file, &actual);
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001644 fclose(policy_file);
1645 ASSERT_NE(res, 0);
1646}
1647
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001648TEST(FilterTest, nonexistent) {
1649 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001650 int res = test_compile_filter("policy", nullptr, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001651 ASSERT_NE(res, 0);
1652}
1653
1654TEST(FilterTest, log) {
1655 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001656 std::string policy =
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001657 "read: 1\n"
1658 "write: 1\n"
1659 "rt_sigreturn: 1\n"
1660 "exit: 1\n";
1661
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001662 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001663 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001664
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001665 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_TRAP,
1666 USE_SIGSYS_LOGGING);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001667 fclose(policy_file);
1668
1669 size_t i;
1670 size_t index = 0;
1671 /*
1672 * Checks return value, filter length, and that the filter
1673 * validates arch, loads syscall number, only allows expected syscalls,
1674 * and returns TRAP on failure.
1675 * NOTE(jorgelo): the filter is longer since we add the syscalls needed
1676 * for logging.
1677 */
1678 ASSERT_EQ(res, 0);
1679 EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len);
1680 EXPECT_ARCH_VALIDATION(actual.filter);
1681 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1682 BPF_LD + BPF_W + BPF_ABS,
1683 syscall_nr);
1684
1685 index = ARCH_VALIDATION_LEN + 1;
1686 for (i = 0; i < log_syscalls_len; i++)
1687 EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i),
1688 lookup_syscall(log_syscalls[i]));
1689
1690 index += 2 * log_syscalls_len;
1691
1692 EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read);
1693 EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write);
1694 EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn);
1695 EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit);
1696 EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET + BPF_K, SECCOMP_RET_TRAP);
1697
1698 free(actual.filter);
1699}
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001700
1701TEST(FilterTest, allow_log_but_kill) {
1702 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001703 std::string policy =
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001704 "read: 1\n"
1705 "write: 1\n"
1706 "rt_sigreturn: 1\n"
1707 "exit: 1\n";
1708
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001709 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001710 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001711
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001712 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_KILL,
1713 USE_SIGSYS_LOGGING);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001714 fclose(policy_file);
1715
1716 size_t i;
1717 size_t index = 0;
1718 /*
1719 * Checks return value, filter length, and that the filter
1720 * validates arch, loads syscall number, only allows expected syscalls,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001721 * and kills on failure.
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001722 * NOTE(jorgelo): the filter is longer since we add the syscalls needed
1723 * for logging.
1724 */
1725 ASSERT_EQ(res, 0);
1726 EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len);
1727 EXPECT_ARCH_VALIDATION(actual.filter);
1728 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1729 BPF_LD+BPF_W+BPF_ABS, syscall_nr);
1730
1731 index = ARCH_VALIDATION_LEN + 1;
1732 for (i = 0; i < log_syscalls_len; i++)
1733 EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i),
1734 lookup_syscall(log_syscalls[i]));
1735
1736 index += 2 * log_syscalls_len;
1737
1738 EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read);
1739 EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write);
1740 EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn);
1741 EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit);
1742 EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET+BPF_K,
1743 SECCOMP_RET_KILL);
1744
1745 free(actual.filter);
1746}
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001747
1748TEST(FilterTest, include_invalid_token) {
1749 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001750 std::string invalid_token = "@unclude ./test/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001751
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001752 FILE* policy_file = write_policy_to_pipe(invalid_token);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001753 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001754 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001755 fclose(policy_file);
1756 EXPECT_NE(res, 0);
1757}
1758
1759TEST(FilterTest, include_no_space) {
1760 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001761 std::string no_space = "@includetest/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001762
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001763 FILE* policy_file = write_policy_to_pipe(no_space);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001764 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001765 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001766 fclose(policy_file);
1767 EXPECT_NE(res, 0);
1768}
1769
1770TEST(FilterTest, include_double_token) {
1771 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001772 std::string double_token = "@includeinclude ./test/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001773
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001774 FILE* policy_file = write_policy_to_pipe(double_token);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001775 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001776 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001777 fclose(policy_file);
1778 EXPECT_NE(res, 0);
1779}
1780
1781TEST(FilterTest, include_no_file) {
1782 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001783 std::string no_file = "@include\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001784
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001785 FILE* policy_file = write_policy_to_pipe(no_file);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001786 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001787 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001788 fclose(policy_file);
1789 EXPECT_NE(res, 0);
1790}
1791
1792TEST(FilterTest, include_space_no_file) {
1793 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001794 std::string space_no_file = "@include \n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001795
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001796 FILE* policy_file = write_policy_to_pipe(space_no_file);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001797 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001798 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001799 fclose(policy_file);
1800 EXPECT_NE(res, 0);
1801}
1802
1803TEST(FilterTest, include_implicit_relative_path) {
1804 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001805 std::string implicit_relative_path = "@include test/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001806
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001807 FILE* policy_file = write_policy_to_pipe(implicit_relative_path);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001808 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001809 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001810 fclose(policy_file);
1811 EXPECT_NE(res, 0);
1812}
1813
1814TEST(FilterTest, include_extra_text) {
1815 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001816 std::string extra_text = "@include /some/file: sneaky comment\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001817
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001818 FILE* policy_file = write_policy_to_pipe(extra_text);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001819 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001820 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001821 fclose(policy_file);
1822 EXPECT_NE(res, 0);
1823}
1824
1825TEST(FilterTest, include_split_filename) {
1826 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001827 std::string split_filename = "@include /some/file:colon.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001828
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001829 FILE* policy_file = write_policy_to_pipe(split_filename);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001830 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001831 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001832 fclose(policy_file);
1833 EXPECT_NE(res, 0);
1834}
1835
1836TEST(FilterTest, include_nonexistent_file) {
1837 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001838 std::string include_policy = "@include ./nonexistent.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001839
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001840 FILE* policy_file = write_policy_to_pipe(include_policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001841 ASSERT_NE(policy_file, nullptr);
1842
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001843 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001844 fclose(policy_file);
1845
1846 ASSERT_NE(res, 0);
1847}
1848
1849// TODO(jorgelo): Android unit tests don't currently support data files.
1850// Re-enable by creating a temporary policy file at runtime.
1851#if !defined(__ANDROID__)
1852
1853TEST(FilterTest, include) {
1854 struct sock_fprog compiled_plain;
1855 struct sock_fprog compiled_with_include;
1856
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001857 std::string policy_plain =
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001858 "read: 1\n"
1859 "write: 1\n"
1860 "rt_sigreturn: 1\n"
1861 "exit: 1\n";
1862
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001863 FILE* file_plain = write_policy_to_pipe(policy_plain);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001864 ASSERT_NE(file_plain, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001865 int res_plain = test_compile_filter("policy", file_plain, &compiled_plain,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001866 ACTION_RET_KILL);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001867 fclose(file_plain);
1868
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001869 std::string policy_with_include =
1870 "@include " + source_path("test/seccomp.policy") + "\n";
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001871
1872 FILE* file_with_include = write_policy_to_pipe(policy_with_include);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001873 ASSERT_NE(file_with_include, nullptr);
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001874 int res_with_include = test_compile_filter(
1875 "policy", file_with_include, &compiled_with_include, ACTION_RET_KILL);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001876 fclose(file_with_include);
1877
1878 /*
1879 * Checks that filter length is the same for a plain policy and an equivalent
1880 * policy with an @include statement. Also checks that the filter generated
1881 * from the policy with an @include statement is exactly the same as one
1882 * generated from a plain policy.
1883 */
1884 ASSERT_EQ(res_plain, 0);
1885 ASSERT_EQ(res_with_include, 0);
1886
1887 EXPECT_EQ(compiled_plain.len, 13);
1888 EXPECT_EQ(compiled_with_include.len, 13);
1889
1890 EXPECT_ARCH_VALIDATION(compiled_with_include.filter);
1891 EXPECT_EQ_STMT(compiled_with_include.filter + ARCH_VALIDATION_LEN,
1892 BPF_LD + BPF_W + BPF_ABS,
1893 syscall_nr);
1894 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 1,
1895 __NR_read);
1896 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 3,
1897 __NR_write);
1898 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 5,
1899 __NR_rt_sigreturn);
1900 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 7,
1901 __NR_exit);
1902 EXPECT_EQ_STMT(compiled_with_include.filter + ARCH_VALIDATION_LEN + 9,
1903 BPF_RET + BPF_K,
1904 SECCOMP_RET_KILL);
1905
1906 free(compiled_plain.filter);
1907 free(compiled_with_include.filter);
1908}
1909
1910TEST(FilterTest, include_same_syscalls) {
1911 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001912 std::string policy =
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001913 "read: 1\n"
1914 "write: 1\n"
1915 "rt_sigreturn: 1\n"
1916 "exit: 1\n"
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001917 "@include " + source_path("test/seccomp.policy") + "\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001918
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001919 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001920 ASSERT_NE(policy_file, nullptr);
1921
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001922 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001923 fclose(policy_file);
1924
1925 ASSERT_EQ(res, 0);
1926 EXPECT_EQ(actual.len,
1927 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ +
1928 2 * 8 /* check syscalls twice */ + 1 /* filter return */);
1929 free(actual.filter);
1930}
1931
Zach Reiznere9260512019-02-27 18:06:34 -08001932TEST(FilterTest, include_two) {
1933 struct sock_fprog actual;
1934 std::string policy =
1935 "@include " + source_path("test/seccomp.policy") + "\n" +
1936 "@include " + source_path("test/seccomp.policy") + "\n";
1937
1938 FILE* policy_file = write_policy_to_pipe(policy);
1939 ASSERT_NE(policy_file, nullptr);
1940
1941 int res = test_compile_filter("policy", policy_file, &actual);
1942 fclose(policy_file);
1943
1944 ASSERT_EQ(res, 0);
1945 EXPECT_EQ(actual.len,
1946 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ +
1947 2 * 8 /* check syscalls twice */ + 1 /* filter return */);
1948 free(actual.filter);
1949}
1950
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001951TEST(FilterTest, include_invalid_policy) {
1952 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001953 std::string policy =
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001954 "read: 1\n"
1955 "write: 1\n"
1956 "rt_sigreturn: 1\n"
1957 "exit: 1\n"
1958 "@include ./test/invalid_syscall_name.policy\n";
1959
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001960 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001961 ASSERT_NE(policy_file, nullptr);
1962
1963 /* Ensure the included (invalid) policy file exists. */
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001964 FILE* included_file = fopen(
1965 source_path("test/invalid_syscall_name.policy").c_str(), "re");
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001966 ASSERT_NE(included_file, nullptr);
1967 fclose(included_file);
1968
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001969 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001970 fclose(policy_file);
1971
1972 ASSERT_NE(res, 0);
1973}
1974
1975TEST(FilterTest, include_nested) {
1976 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001977 std::string policy = "@include ./test/nested.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001978
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001979 FILE* policy_file = write_policy_to_pipe(policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001980 ASSERT_NE(policy_file, nullptr);
1981
1982 /* Ensure the policy file exists. */
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001983 FILE* included_file = fopen(source_path("test/nested.policy").c_str(), "re");
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001984 ASSERT_NE(included_file, nullptr);
1985 fclose(included_file);
1986
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001987 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001988 fclose(policy_file);
1989
1990 ASSERT_NE(res, 0);
1991}
1992
Mike Frysingercdfb0cc2019-03-15 01:39:00 -04001993#endif // !__ANDROID__
1994
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07001995TEST(FilterTest, error_cleanup_leak) {
1996 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001997 std::string policy =
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07001998 "read:&&\n"
1999 "read:&&";
2000
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04002001 FILE* policy_file = write_policy_to_pipe(policy);
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07002002 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04002003 int res = test_compile_filter("policy", policy_file, &actual);
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07002004 fclose(policy_file);
2005
2006 /*
2007 * Policy is malformed, but process should not leak.
2008 */
2009 ASSERT_EQ(res, -1);
2010}