blob: 79755f9f0d8711ea8777efb76604a94148a8e055 [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"
Zi Lin171ee1e2021-10-13 03:12:18 +000018#include "test_util.h"
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -040019#include "util.h"
20
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040021namespace {
22
23// Simple C++ -> C wrappers to simplify test code.
24
25enum ret_trap {
26 USE_RET_KILL = 0,
27 USE_RET_TRAP = 1,
28};
29
30enum use_logging {
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040031 NO_LOGGING = 0,
32 USE_SIGSYS_LOGGING = 1,
33 USE_RET_LOG_LOGGING = 2,
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040034};
35
36int test_compile_filter(
Christian Blichmann2b9f5be2022-01-10 15:56:25 +010037 const std::string& filename,
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040038 FILE* policy_file,
39 struct sock_fprog* prog,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040040 enum block_action action = ACTION_RET_KILL,
Nicole Anderson-Auaba39462020-11-09 23:36:56 +000041 enum use_logging allow_logging = NO_LOGGING,
42 bool allow_dup_syscalls = true) {
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040043 struct filter_options filteropts {
44 .action = action,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040045 .allow_logging = allow_logging != NO_LOGGING,
46 .allow_syscalls_for_logging = allow_logging == USE_SIGSYS_LOGGING,
Nicole Anderson-Auaba39462020-11-09 23:36:56 +000047 .allow_duplicate_syscalls = allow_dup_syscalls,
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040048 };
49 return compile_filter(filename.c_str(), policy_file, prog, &filteropts);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040050}
51
52int test_compile_file(
53 std::string filename,
54 FILE* policy_file,
55 struct filter_block* head,
56 struct filter_block** arg_blocks,
57 struct bpf_labels* labels,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040058 enum block_action action = ACTION_RET_KILL,
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040059 enum use_logging allow_logging = NO_LOGGING,
Nicole Anderson-Auaba39462020-11-09 23:36:56 +000060 unsigned int include_level = 0,
61 bool allow_dup_syscalls = false) {
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040062 struct filter_options filteropts {
63 .action = action,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040064 .allow_logging = allow_logging != NO_LOGGING,
65 .allow_syscalls_for_logging = allow_logging == USE_SIGSYS_LOGGING,
Nicole Anderson-Auaba39462020-11-09 23:36:56 +000066 .allow_duplicate_syscalls = allow_dup_syscalls,
Jorge Lucangeli Obese1a86892019-06-10 16:17:03 -040067 };
Nicole Anderson-Aubcc8cfd2020-11-10 20:33:27 +000068 size_t num_syscalls = get_num_syscalls();
69 struct parser_state **previous_syscalls =
70 (struct parser_state **)calloc(num_syscalls,
71 sizeof(struct parser_state *));
72 int res = compile_file(filename.c_str(), policy_file, head, arg_blocks,
73 labels, &filteropts, previous_syscalls,
74 include_level);
75 free_previous_syscalls(previous_syscalls);
76 return res;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040077}
78
79struct filter_block* test_compile_policy_line(
80 struct parser_state* state,
81 int nr,
Christian Blichmann2b9f5be2022-01-10 15:56:25 +010082 const std::string& policy_line,
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040083 unsigned int label_id,
84 struct bpf_labels* labels,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040085 enum block_action action = ACTION_RET_KILL) {
86 return compile_policy_line(state, nr, policy_line.c_str(), label_id,
87 labels, action);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -040088}
89
90} // namespace
91
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -040092/* Test that setting one BPF instruction works. */
93TEST(bpf, set_bpf_instr) {
94 struct sock_filter instr;
95 unsigned char code = BPF_LD + BPF_W + BPF_ABS;
96 unsigned int k = 4;
97 unsigned char jt = 1, jf = 2;
98
99 size_t len = set_bpf_instr(&instr, code, k, jt, jf);
100
101 EXPECT_EQ(len, 1U);
102 EXPECT_EQ_BLOCK(&instr, code, k, jt, jf);
103}
104
105TEST(bpf, bpf_load_arg) {
106 struct sock_filter load_arg[BPF_LOAD_ARG_LEN];
Jorge Lucangeli Obes9bd316b2017-01-26 17:21:16 -0500107 const int argidx = 1;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400108 size_t len = bpf_load_arg(load_arg, argidx);
109
110 EXPECT_EQ(len, BPF_LOAD_ARG_LEN);
111
112#if defined(BITS32)
113 EXPECT_EQ_STMT(&load_arg[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
114#elif defined(BITS64)
115 EXPECT_EQ_STMT(&load_arg[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
116 EXPECT_EQ_STMT(&load_arg[1], BPF_ST, 0);
117 EXPECT_EQ_STMT(&load_arg[2], BPF_LD + BPF_W + BPF_ABS, HI_ARG(argidx));
118 EXPECT_EQ_STMT(&load_arg[3], BPF_ST, 1);
119#endif
120}
121
122TEST(bpf, bpf_comp_jeq) {
123 struct sock_filter comp_jeq[BPF_COMP_LEN];
124 unsigned long c = 1;
125 unsigned char jt = 1;
126 unsigned char jf = 2;
127
128 size_t len = bpf_comp_jeq(comp_jeq, c, jt, jf);
129
130 EXPECT_EQ(len, BPF_COMP_LEN);
131
132#if defined(BITS32)
133 EXPECT_EQ_BLOCK(&comp_jeq[0], BPF_JMP + BPF_JEQ + BPF_K, c, jt, jf);
134#elif defined(BITS64)
135 EXPECT_EQ_BLOCK(&comp_jeq[0], BPF_JMP + BPF_JEQ + BPF_K, 0, 0, jf + 2);
136 EXPECT_EQ_STMT(&comp_jeq[1], BPF_LD + BPF_MEM, 0);
137 EXPECT_EQ_BLOCK(&comp_jeq[2], BPF_JMP + BPF_JEQ + BPF_K, c, jt, jf);
138#endif
139}
140
141TEST(bpf, bpf_comp_jset) {
142 struct sock_filter comp_jset[BPF_COMP_LEN];
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400143 unsigned long mask = (1UL << (sizeof(unsigned long) * 8 - 1)) | O_WRONLY;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400144 unsigned char jt = 1;
145 unsigned char jf = 2;
146
147 size_t len = bpf_comp_jset(comp_jset, mask, jt, jf);
148
149 EXPECT_EQ(len, BPF_COMP_LEN);
150
151#if defined(BITS32)
152 EXPECT_EQ_BLOCK(&comp_jset[0], BPF_JMP + BPF_JSET + BPF_K, mask, jt, jf);
153#elif defined(BITS64)
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400154 EXPECT_EQ_BLOCK(
155 &comp_jset[0], BPF_JMP + BPF_JSET + BPF_K, 0x80000000, jt + 2, 0);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400156 EXPECT_EQ_STMT(&comp_jset[1], BPF_LD + BPF_MEM, 0);
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400157 EXPECT_EQ_BLOCK(&comp_jset[2], BPF_JMP + BPF_JSET + BPF_K, O_WRONLY, jt, jf);
158#endif
159}
160
161TEST(bpf, bpf_comp_jin) {
162 struct sock_filter comp_jin[BPF_COMP_LEN];
163 unsigned long mask = (1UL << (sizeof(unsigned long) * 8 - 1)) | O_WRONLY;
164 unsigned char jt = 10;
165 unsigned char jf = 20;
166
167 size_t len = bpf_comp_jin(comp_jin, mask, jt, jf);
168
169 EXPECT_EQ(len, BPF_COMP_LEN);
170
171#if defined(BITS32)
172 EXPECT_EQ_BLOCK(&comp_jin[0], BPF_JMP + BPF_JSET + BPF_K, ~mask, jf, jt);
173#elif defined(BITS64)
174 EXPECT_EQ_BLOCK(
175 &comp_jin[0], BPF_JMP + BPF_JSET + BPF_K, 0x7FFFFFFF, jf + 2, 0);
176 EXPECT_EQ_STMT(&comp_jin[1], BPF_LD + BPF_MEM, 0);
177 EXPECT_EQ_BLOCK(&comp_jin[2], BPF_JMP + BPF_JSET + BPF_K, ~O_WRONLY, jf, jt);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400178#endif
179}
180
181TEST(bpf, bpf_arg_comp) {
182 struct sock_filter *arg_comp;
183 int op = EQ;
Jorge Lucangeli Obes9bd316b2017-01-26 17:21:16 -0500184 const int argidx = 1;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400185 unsigned long c = 3;
186 unsigned int label_id = 0;
187
188 size_t len = bpf_arg_comp(&arg_comp, op, argidx, c, label_id);
189
190 EXPECT_EQ(len, BPF_ARG_COMP_LEN + 1);
191
192#if defined(BITS32)
193 EXPECT_EQ_STMT(&arg_comp[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
194 EXPECT_EQ_BLOCK(&arg_comp[1], BPF_JMP + BPF_JEQ + BPF_K, c, 1, 0);
195 EXPECT_JUMP_LBL(&arg_comp[2]);
196#elif defined(BITS64)
197 EXPECT_EQ_STMT(&arg_comp[0], BPF_LD + BPF_W + BPF_ABS, LO_ARG(argidx));
198 EXPECT_EQ_STMT(&arg_comp[1], BPF_ST, 0);
199 EXPECT_EQ_STMT(&arg_comp[2], BPF_LD + BPF_W + BPF_ABS, HI_ARG(argidx));
200 EXPECT_EQ_STMT(&arg_comp[3], BPF_ST, 1);
201
202 EXPECT_EQ_BLOCK(&arg_comp[4], BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 2);
203 EXPECT_EQ_STMT(&arg_comp[5], BPF_LD + BPF_MEM, 0);
204 EXPECT_EQ_BLOCK(&arg_comp[6], BPF_JMP + BPF_JEQ + BPF_K, c, 1, 0);
205 EXPECT_JUMP_LBL(&arg_comp[7]);
206#endif
207 free(arg_comp);
208}
209
210TEST(bpf, bpf_validate_arch) {
211 struct sock_filter validate_arch[ARCH_VALIDATION_LEN];
212
213 size_t len = bpf_validate_arch(validate_arch);
214
215 EXPECT_EQ(len, ARCH_VALIDATION_LEN);
216 EXPECT_ARCH_VALIDATION(validate_arch);
217}
218
219TEST(bpf, bpf_allow_syscall) {
220 struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN];
221 int nr = 1;
222
223 size_t len = bpf_allow_syscall(allow_syscall, nr);
224
225 EXPECT_EQ(len, ALLOW_SYSCALL_LEN);
226 EXPECT_ALLOW_SYSCALL(allow_syscall, nr);
227}
228
229TEST(bpf, bpf_allow_syscall_args) {
230 struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN];
231 int nr = 1;
232 unsigned int id = 1024;
233
234 size_t len = bpf_allow_syscall_args(allow_syscall, nr, id);
235
236 EXPECT_EQ(len, ALLOW_SYSCALL_LEN);
237 EXPECT_ALLOW_SYSCALL_ARGS(allow_syscall, nr, id, JUMP_JT, JUMP_JF);
238}
239
Jorge Lucangeli Obes8cc9d4a2016-10-03 10:00:57 -0400240class BpfLabelTest : public ::testing::Test {
241 protected:
Jorge Lucangeli Obes9bd316b2017-01-26 17:21:16 -0500242 virtual void SetUp() { labels_.count = 0; }
Jorge Lucangeli Obes8cc9d4a2016-10-03 10:00:57 -0400243 virtual void TearDown() { free_label_strings(&labels_); }
244 struct bpf_labels labels_;
245};
246
247TEST_F(BpfLabelTest, zero_length_filter) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400248 int res = bpf_resolve_jumps(&labels_, nullptr, 0);
Jorge Lucangeli Obes8cc9d4a2016-10-03 10:00:57 -0400249
250 EXPECT_EQ(res, 0);
251 EXPECT_EQ(labels_.count, 0U);
252}
253
254TEST_F(BpfLabelTest, single_label) {
255 struct sock_filter test_label[1];
256
257 int id = bpf_label_id(&labels_, "test");
258 set_bpf_lbl(test_label, id);
259 int res = bpf_resolve_jumps(&labels_, test_label, 1);
260
261 EXPECT_EQ(res, 0);
262 EXPECT_EQ(labels_.count, 1U);
263}
264
265TEST_F(BpfLabelTest, repeated_label) {
266 struct sock_filter test_label[2];
267
268 int id = bpf_label_id(&labels_, "test");
269 set_bpf_lbl(&test_label[0], id);
270 set_bpf_lbl(&test_label[1], id);
271 int res = bpf_resolve_jumps(&labels_, test_label, 2);
272
273 EXPECT_EQ(res, -1);
274}
275
276TEST_F(BpfLabelTest, jump_with_no_label) {
277 struct sock_filter test_jump[1];
278
279 set_bpf_jump_lbl(test_jump, 14831);
280 int res = bpf_resolve_jumps(&labels_, test_jump, 1);
281
282 EXPECT_EQ(res, -1);
283}
284
285TEST_F(BpfLabelTest, jump_to_valid_label) {
286 struct sock_filter test_jump[2];
287
288 int id = bpf_label_id(&labels_, "test");
289 set_bpf_jump_lbl(&test_jump[0], id);
290 set_bpf_lbl(&test_jump[1], id);
291
292 int res = bpf_resolve_jumps(&labels_, test_jump, 2);
293 EXPECT_EQ(res, 0);
294 EXPECT_EQ(labels_.count, 1U);
295}
296
297TEST_F(BpfLabelTest, jump_to_invalid_label) {
298 struct sock_filter test_jump[2];
299
300 int id = bpf_label_id(&labels_, "test");
301 set_bpf_jump_lbl(&test_jump[0], id + 1);
302 set_bpf_lbl(&test_jump[1], id);
303
304 int res = bpf_resolve_jumps(&labels_, test_jump, 2);
305 EXPECT_EQ(res, -1);
306}
307
308TEST_F(BpfLabelTest, jump_to_unresolved_label) {
309 struct sock_filter test_jump[2];
310
311 int id = bpf_label_id(&labels_, "test");
312 /* Notice the order of the instructions is reversed. */
313 set_bpf_lbl(&test_jump[0], id);
314 set_bpf_jump_lbl(&test_jump[1], id);
315
316 int res = bpf_resolve_jumps(&labels_, test_jump, 2);
317 EXPECT_EQ(res, -1);
318}
319
320TEST_F(BpfLabelTest, too_many_labels) {
321 unsigned int i;
322 char label[20];
323
324 for (i = 0; i < BPF_LABELS_MAX; i++) {
325 snprintf(label, 20, "test%u", i);
326 (void) bpf_label_id(&labels_, label);
327 }
328 int id = bpf_label_id(&labels_, "test");
329
330 /* Insertion failed... */
331 EXPECT_EQ(id, -1);
332 /* ... because the label lookup table is full. */
333 EXPECT_EQ(labels_.count, BPF_LABELS_MAX);
334}
335
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400336class ArgFilterTest : public ::testing::Test {
337 protected:
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700338 virtual void SetUp() {
339 labels_.count = 0;
340 state_.filename = "policy";
341 state_.line_number = 1;
342 }
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400343 virtual void TearDown() { free_label_strings(&labels_); }
344 struct bpf_labels labels_;
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700345 int nr_ = 1;
346 unsigned int id_ = 0;
347 struct parser_state state_;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400348};
349
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400350TEST_F(ArgFilterTest, empty_atom) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400351 std::string fragment = "";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400352
353 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400354 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400355 ASSERT_EQ(block, nullptr);
356}
357
358TEST_F(ArgFilterTest, whitespace_atom) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400359 std::string fragment = "\t ";
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400360
361 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400362 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400363 ASSERT_EQ(block, nullptr);
364}
365
366TEST_F(ArgFilterTest, no_comparison) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400367 std::string fragment = "arg0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400368
369 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400370 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400371 ASSERT_EQ(block, nullptr);
372}
373
374TEST_F(ArgFilterTest, no_constant) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400375 std::string fragment = "arg0 ==";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400376
377 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400378 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400379 ASSERT_EQ(block, nullptr);
380}
381
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400382TEST_F(ArgFilterTest, arg0_equals) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400383 std::string fragment = "arg0 == 0";
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700384
385 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400386 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400387
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400388 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400389 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
390 EXPECT_EQ(block->total_len, exp_total_len);
391
392 /* First block is a label. */
393 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400394 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400395 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400396 EXPECT_LBL(curr_block->instrs);
397
398 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400399 curr_block = curr_block->next;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400400 EXPECT_COMP(curr_block);
401
402 /* Third block is a jump and a label (end of AND group). */
403 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400404 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400405 EXPECT_GROUP_END(curr_block);
406
407 /* Fourth block is SECCOMP_RET_KILL. */
408 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400409 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400410 EXPECT_KILL(curr_block);
411
412 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
413 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400414 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400415 EXPECT_ALLOW(curr_block);
416
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400417 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400418
419 free_block_list(block);
420}
421
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -0400422TEST_F(ArgFilterTest, arg0_equals_trap) {
423 std::string fragment = "arg0 == 0";
424
425 struct filter_block* block = test_compile_policy_line(
426 &state_, nr_, fragment, id_, &labels_, ACTION_RET_TRAP);
427
428 ASSERT_NE(block, nullptr);
429 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
430 EXPECT_EQ(block->total_len, exp_total_len);
431
432 /* First block is a label. */
433 struct filter_block* curr_block = block;
434 ASSERT_NE(curr_block, nullptr);
435 EXPECT_EQ(curr_block->len, 1U);
436 EXPECT_LBL(curr_block->instrs);
437
438 /* Second block is a comparison. */
439 curr_block = curr_block->next;
440 EXPECT_COMP(curr_block);
441
442 /* Third block is a jump and a label (end of AND group). */
443 curr_block = curr_block->next;
444 ASSERT_NE(curr_block, nullptr);
445 EXPECT_GROUP_END(curr_block);
446
447 /* Fourth block is SECCOMP_RET_TRAP. */
448 curr_block = curr_block->next;
449 ASSERT_NE(curr_block, nullptr);
450 EXPECT_TRAP(curr_block);
451
452 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
453 curr_block = curr_block->next;
454 ASSERT_NE(curr_block, nullptr);
455 EXPECT_ALLOW(curr_block);
456
457 EXPECT_EQ(curr_block->next, nullptr);
458
459 free_block_list(block);
460}
461
462TEST_F(ArgFilterTest, arg0_equals_log) {
463 std::string fragment = "arg0 == 0";
464
465 struct filter_block* block = test_compile_policy_line(
466 &state_, nr_, fragment, id_, &labels_, ACTION_RET_LOG);
467
468 ASSERT_NE(block, nullptr);
469 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
470 EXPECT_EQ(block->total_len, exp_total_len);
471
472 /* First block is a label. */
473 struct filter_block* curr_block = block;
474 ASSERT_NE(curr_block, nullptr);
475 EXPECT_EQ(curr_block->len, 1U);
476 EXPECT_LBL(curr_block->instrs);
477
478 /* Second block is a comparison. */
479 curr_block = curr_block->next;
480 EXPECT_COMP(curr_block);
481
482 /* Third block is a jump and a label (end of AND group). */
483 curr_block = curr_block->next;
484 ASSERT_NE(curr_block, nullptr);
485 EXPECT_GROUP_END(curr_block);
486
487 /* Fourth block is SECCOMP_RET_LOG. */
488 curr_block = curr_block->next;
489 ASSERT_NE(curr_block, nullptr);
490 EXPECT_LOG(curr_block);
491
492 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
493 curr_block = curr_block->next;
494 ASSERT_NE(curr_block, nullptr);
495 EXPECT_ALLOW(curr_block);
496
497 EXPECT_EQ(curr_block->next, nullptr);
498
499 free_block_list(block);
500}
501
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700502TEST_F(ArgFilterTest, arg0_short_gt_ge_comparisons) {
Christian Blichmann2b9f5be2022-01-10 15:56:25 +0100503 for (const std::string fragment :
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700504 {"arg1 < 0xff", "arg1 <= 0xff", "arg1 > 0xff", "arg1 >= 0xff"}) {
505 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400506 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700507
508 ASSERT_NE(block, nullptr);
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700509 size_t exp_total_len = 1 + (BPF_ARG_SHORT_GT_GE_COMP_LEN + 1) + 2 + 1 + 2;
510 EXPECT_EQ(block->total_len, exp_total_len);
511
512 // First block is a label.
513 struct filter_block* curr_block = block;
514 ASSERT_NE(curr_block, nullptr);
515 EXPECT_EQ(curr_block->len, 1U);
516 EXPECT_LBL(curr_block->instrs);
517
518 // Second block is a short gt/ge comparison.
519 curr_block = curr_block->next;
520 EXPECT_SHORT_GT_GE_COMP(curr_block);
521
522 // Third block is a jump and a label (end of AND group).
523 curr_block = curr_block->next;
524 ASSERT_NE(curr_block, nullptr);
525 EXPECT_GROUP_END(curr_block);
526
527 // Fourth block is SECCOMP_RET_KILL.
528 curr_block = curr_block->next;
529 ASSERT_NE(curr_block, nullptr);
530 EXPECT_KILL(curr_block);
531
532 // Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW.
533 curr_block = curr_block->next;
534 ASSERT_NE(curr_block, nullptr);
535 EXPECT_ALLOW(curr_block);
536
537 EXPECT_EQ(curr_block->next, nullptr);
538
539 free_block_list(block);
540 }
541}
542
543#if defined(BITS64)
544TEST_F(ArgFilterTest, arg0_long_gt_ge_comparisons) {
Christian Blichmann2b9f5be2022-01-10 15:56:25 +0100545 for (const std::string fragment :
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700546 {"arg1 < 0xbadc0ffee0ddf00d", "arg1 <= 0xbadc0ffee0ddf00d",
547 "arg1 > 0xbadc0ffee0ddf00d", "arg1 >= 0xbadc0ffee0ddf00d"}) {
548 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400549 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700550
551 ASSERT_NE(block, nullptr);
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700552 size_t exp_total_len = 1 + (BPF_ARG_GT_GE_COMP_LEN + 1) + 2 + 1 + 2;
553 EXPECT_EQ(block->total_len, exp_total_len);
554
555 // First block is a label.
556 struct filter_block* curr_block = block;
557 ASSERT_NE(curr_block, nullptr);
558 EXPECT_EQ(curr_block->len, 1U);
559 EXPECT_LBL(curr_block->instrs);
560
561 // Second block is a gt/ge comparison.
562 curr_block = curr_block->next;
563 EXPECT_GT_GE_COMP(curr_block);
564
565 // Third block is a jump and a label (end of AND group).
566 curr_block = curr_block->next;
567 ASSERT_NE(curr_block, nullptr);
568 EXPECT_GROUP_END(curr_block);
569
570 // Fourth block is SECCOMP_RET_KILL.
571 curr_block = curr_block->next;
572 ASSERT_NE(curr_block, nullptr);
573 EXPECT_KILL(curr_block);
574
575 // Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW.
576 curr_block = curr_block->next;
577 ASSERT_NE(curr_block, nullptr);
578 EXPECT_ALLOW(curr_block);
579
580 EXPECT_EQ(curr_block->next, nullptr);
581
582 free_block_list(block);
583 }
584}
Luis Hector Chavez136adca2018-07-21 22:45:56 -0700585#endif
Luis Hector Chavez1c937832018-07-21 22:45:47 -0700586
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400587TEST_F(ArgFilterTest, arg0_mask) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400588 std::string fragment = "arg1 & O_RDWR";
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700589
590 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400591 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400592
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400593 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400594 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
595 EXPECT_EQ(block->total_len, exp_total_len);
596
597 /* First block is a label. */
598 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400599 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400600 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400601 EXPECT_LBL(curr_block->instrs);
602
603 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400604 curr_block = curr_block->next;
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400605 EXPECT_COMP(curr_block);
606
607 /* Third block is a jump and a label (end of AND group). */
608 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400609 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400610 EXPECT_GROUP_END(curr_block);
611
612 /* Fourth block is SECCOMP_RET_KILL. */
613 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400614 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400615 EXPECT_KILL(curr_block);
616
617 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
618 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400619 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400620 EXPECT_ALLOW(curr_block);
621
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400622 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400623
624 free_block_list(block);
625}
626
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400627TEST_F(ArgFilterTest, arg0_flag_set_inclusion) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400628 std::string fragment = "arg0 in O_RDONLY|O_CREAT";
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700629
630 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400631 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400632
633 ASSERT_NE(block, nullptr);
634 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
635 EXPECT_EQ(block->total_len, exp_total_len);
636
637 /* First block is a label. */
638 struct filter_block *curr_block = block;
639 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400640 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400641 EXPECT_LBL(curr_block->instrs);
642
643 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400644 curr_block = curr_block->next;
Jorge Lucangeli Obesfd6f8e32016-10-12 11:19:28 -0400645 ASSERT_NE(curr_block, nullptr);
646 EXPECT_COMP(curr_block);
647
648 /* Third block is a jump and a label (end of AND group). */
649 curr_block = curr_block->next;
650 ASSERT_NE(curr_block, nullptr);
651 EXPECT_GROUP_END(curr_block);
652
653 /* Fourth block is SECCOMP_RET_KILL. */
654 curr_block = curr_block->next;
655 ASSERT_NE(curr_block, nullptr);
656 EXPECT_KILL(curr_block);
657
658 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
659 curr_block = curr_block->next;
660 ASSERT_NE(curr_block, nullptr);
661 EXPECT_ALLOW(curr_block);
662
663 EXPECT_EQ(curr_block->next, nullptr);
664
665 free_block_list(block);
666}
667
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400668TEST_F(ArgFilterTest, arg0_eq_mask) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400669 std::string fragment = "arg1 == O_WRONLY|O_CREAT";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400670
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700671 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400672 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400673
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400674 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400675 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
676 EXPECT_EQ(block->total_len, exp_total_len);
677
678 /* First block is a label. */
679 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400680 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400681 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400682 EXPECT_LBL(curr_block->instrs);
683
684 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400685 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400686 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400687 EXPECT_COMP(curr_block);
688 EXPECT_EQ(curr_block->instrs[BPF_ARG_COMP_LEN - 1].k,
689 (unsigned int)(O_WRONLY | O_CREAT));
690
691 /* Third block is a jump and a label (end of AND group). */
692 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400693 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400694 EXPECT_GROUP_END(curr_block);
695
696 /* Fourth block is SECCOMP_RET_KILL. */
697 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400698 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400699 EXPECT_KILL(curr_block);
700
701 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
702 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400703 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400704 EXPECT_ALLOW(curr_block);
705
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400706 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400707
708 free_block_list(block);
709}
710
711TEST_F(ArgFilterTest, and_or) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400712 std::string fragment = "arg0 == 0 && arg1 == 0 || arg0 == 1";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400713
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700714 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400715 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400716 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400717 size_t exp_total_len = 1 + 3 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2;
718 EXPECT_EQ(block->total_len, exp_total_len);
719
720 /* First block is a label. */
721 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400722 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400723 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400724 EXPECT_LBL(curr_block->instrs);
725
726 /* Second block is a comparison ("arg0 == 0"). */
727 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400728 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400729 EXPECT_COMP(curr_block);
730
731 /* Third block is a comparison ("arg1 == 0"). */
732 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400733 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400734 EXPECT_COMP(curr_block);
735
736 /* Fourth block is a jump and a label (end of AND group). */
737 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400738 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400739 EXPECT_GROUP_END(curr_block);
740
741 /* Fifth block is a comparison ("arg0 == 1"). */
742 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400743 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400744 EXPECT_COMP(curr_block);
745
746 /* Sixth block is a jump and a label (end of AND group). */
747 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400748 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400749 EXPECT_GROUP_END(curr_block);
750
751 /* Seventh block is SECCOMP_RET_KILL. */
752 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400753 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400754 EXPECT_KILL(curr_block);
755
756 /* Eigth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
757 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400758 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400759 EXPECT_ALLOW(curr_block);
760
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400761 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400762
763 free_block_list(block);
764}
765
766TEST_F(ArgFilterTest, ret_errno) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400767 std::string fragment = "arg0 == 0 || arg0 == 1; return 1";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400768
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700769 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400770 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400771 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400772 size_t exp_total_len = 1 + 2 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2;
773 EXPECT_EQ(block->total_len, exp_total_len);
774
775 /* First block is a label. */
776 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400777 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400778 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400779 EXPECT_LBL(curr_block->instrs);
780
781 /* Second block is a comparison ("arg0 == 0"). */
782 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400783 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400784 EXPECT_COMP(curr_block);
785
786 /* Third block is a jump and a label (end of AND group). */
787 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400788 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400789 EXPECT_GROUP_END(curr_block);
790
791 /* Fourth block is a comparison ("arg0 == 1"). */
792 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400793 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400794 EXPECT_COMP(curr_block);
795
796 /* Fifth block is a jump and a label (end of AND group). */
797 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400798 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400799 EXPECT_GROUP_END(curr_block);
800
801 /* Sixth block is SECCOMP_RET_ERRNO. */
802 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400803 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400804 EXPECT_EQ(curr_block->len, 1U);
805 EXPECT_EQ_STMT(curr_block->instrs,
806 BPF_RET + BPF_K,
807 SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA));
808
809 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
810 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400811 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400812 EXPECT_ALLOW(curr_block);
813
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400814 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400815
816 free_block_list(block);
817}
818
819TEST_F(ArgFilterTest, unconditional_errno) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400820 std::string fragment = "return 1";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400821
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700822 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400823 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400824 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400825 size_t exp_total_len = 2;
826 EXPECT_EQ(block->total_len, exp_total_len);
827
828 /* First block is a label. */
829 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400830 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400831 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400832 EXPECT_LBL(curr_block->instrs);
833
834 /* Second block is SECCOMP_RET_ERRNO. */
835 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400836 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400837 EXPECT_EQ(curr_block->len, 1U);
838 EXPECT_EQ_STMT(curr_block->instrs,
839 BPF_RET + BPF_K,
840 SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA));
841
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400842 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400843
844 free_block_list(block);
845}
846
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400847TEST_F(ArgFilterTest, invalid_arg_token) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400848 std::string fragment = "org0 == 0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400849
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700850 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400851 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400852 ASSERT_EQ(block, nullptr);
853}
854
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400855TEST_F(ArgFilterTest, invalid_arg_number) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400856 std::string fragment = "argnn == 0";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400857
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700858 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400859 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400860 ASSERT_EQ(block, nullptr);
861}
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400862
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400863TEST_F(ArgFilterTest, extra_chars_in_arg_token) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400864 std::string fragment = "arg0n == 0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400865
866 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400867 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400868 ASSERT_EQ(block, nullptr);
869}
870
871TEST_F(ArgFilterTest, invalid_operator) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400872 std::string fragment = "arg0 invalidop 0";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400873
874 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400875 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400876 ASSERT_EQ(block, nullptr);
877}
878
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400879TEST_F(ArgFilterTest, invalid_constant) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400880 std::string fragment = "arg0 == INVALIDCONSTANT";
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400881
882 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400883 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400884 ASSERT_EQ(block, nullptr);
885}
886
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400887TEST_F(ArgFilterTest, extra_tokens) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400888 std::string fragment = "arg0 == 0 EXTRATOKEN";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400889
890 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400891 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -0400892 ASSERT_EQ(block, nullptr);
893}
894
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400895TEST_F(ArgFilterTest, invalid_errno) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400896 std::string fragment = "arg0 == 0 && arg1 == 1; return errno";
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400897
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700898 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400899 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obes53895402016-10-18 12:02:58 -0400900 ASSERT_EQ(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400901}
902
903TEST_F(ArgFilterTest, log_no_ret_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400904 std::string fragment = "arg0 == 0";
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700905
906 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400907 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -0400908 ACTION_RET_TRAP);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400909
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400910 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400911 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
912 EXPECT_EQ(block->total_len, exp_total_len);
913
914 /* First block is a label. */
915 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400916 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400917 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400918 EXPECT_LBL(curr_block->instrs);
919
920 /* Second block is a comparison. */
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400921 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400922 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400923 EXPECT_COMP(curr_block);
924
925 /* Third block is a jump and a label (end of AND group). */
926 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400927 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400928 EXPECT_GROUP_END(curr_block);
929
930 /* Fourth block is SECCOMP_RET_TRAP, with no errno. */
931 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400932 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400933 EXPECT_TRAP(curr_block);
934
935 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
936 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400937 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400938 EXPECT_ALLOW(curr_block);
939
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400940 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400941
942 free_block_list(block);
943}
944
945TEST_F(ArgFilterTest, log_bad_ret_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400946 std::string fragment = "arg0 == 0; return";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400947
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700948 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400949 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400950 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400951 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
952 EXPECT_EQ(block->total_len, exp_total_len);
953
954 /* First block is a label. */
955 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400956 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -0400957 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400958 EXPECT_LBL(curr_block->instrs);
959
960 /* Second block is a comparison ("arg0 == 0"). */
961 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400962 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400963 EXPECT_COMP(curr_block);
964
965 /* Third block is a jump and a label (end of AND group). */
966 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400967 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400968 EXPECT_GROUP_END(curr_block);
969
970 /*
971 * Sixth block is NOT SECCOMP_RET_ERRNO, it should be SECCOMP_RET_KILL.
972 */
973 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400974 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400975 EXPECT_KILL(curr_block);
976
977 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
978 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400979 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400980 EXPECT_ALLOW(curr_block);
981
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400982 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400983
984 free_block_list(block);
985}
986
987TEST_F(ArgFilterTest, no_log_bad_ret_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400988 std::string fragment = "arg0 == 0; return";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400989
Luis Hector Chavez7624e712017-08-28 19:30:59 -0700990 struct filter_block* block =
Mike Frysinger68a1b3b2018-08-15 17:00:18 -0400991 test_compile_policy_line(&state_, nr_, fragment, id_, &labels_,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -0400992 ACTION_RET_TRAP);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400993 ASSERT_NE(block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -0400994 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
995 EXPECT_EQ(block->total_len, exp_total_len);
996
997 /* First block is a label. */
998 struct filter_block *curr_block = block;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400999 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001000 EXPECT_EQ(curr_block->len, 1U);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001001 EXPECT_LBL(curr_block->instrs);
1002
1003 /* Second block is a comparison ("arg0 == 0"). */
1004 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001005 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001006 EXPECT_COMP(curr_block);
1007
1008 /* Third block is a jump and a label (end of AND group). */
1009 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001010 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001011 EXPECT_GROUP_END(curr_block);
1012
1013 /*
1014 * Sixth block is *not* SECCOMP_RET_ERRNO, it should be
1015 * SECCOMP_RET_TRAP.
1016 */
1017 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001018 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001019 EXPECT_TRAP(curr_block);
1020
1021 /* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
1022 curr_block = curr_block->next;
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001023 ASSERT_NE(curr_block, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001024 EXPECT_ALLOW(curr_block);
1025
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001026 EXPECT_EQ(curr_block->next, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001027
1028 free_block_list(block);
1029}
1030
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001031namespace {
1032
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001033class FileTest : public ::testing::Test {
1034 protected:
1035 virtual void SetUp() {
1036 labels_.count = 0;
1037 head_ = new_filter_block();
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001038 arg_blocks_ = nullptr;
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001039 }
1040 virtual void TearDown() {
1041 free_label_strings(&labels_);
1042 free_block_list(head_);
1043 free_block_list(arg_blocks_);
1044 }
1045 struct bpf_labels labels_;
1046 struct filter_block *head_;
1047 struct filter_block *arg_blocks_;
1048};
1049
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001050} // namespace
1051
lhchavezd0b40702017-09-01 04:17:41 +00001052TEST_F(FileTest, malformed_policy) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001053 std::string policy =
lhchavezd0b40702017-09-01 04:17:41 +00001054 "malformed";
1055
Zi Lin171ee1e2021-10-13 03:12:18 +00001056 FILE* policy_file = write_to_pipe(policy);
lhchavezd0b40702017-09-01 04:17:41 +00001057 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001058 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1059 &labels_);
lhchavezd0b40702017-09-01 04:17:41 +00001060 fclose(policy_file);
1061
1062 /*
1063 * Policy is malformed, but process should not crash.
1064 */
1065 ASSERT_EQ(res, -1);
1066}
1067
lhchavezd38280c2017-09-01 14:00:05 +00001068TEST_F(FileTest, double_free_on_compile_error) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001069 std::string policy =
lhchavezd38280c2017-09-01 14:00:05 +00001070 "read:arg0 == 0\n"
1071 "write:0";
1072
Zi Lin171ee1e2021-10-13 03:12:18 +00001073 FILE* policy_file = write_to_pipe(policy);
lhchavezd38280c2017-09-01 14:00:05 +00001074 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001075 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1076 &labels_);
lhchavezd38280c2017-09-01 14:00:05 +00001077 fclose(policy_file);
1078
1079 /*
1080 * Policy is malformed, but process should not crash.
1081 */
1082 ASSERT_EQ(res, -1);
1083}
1084
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001085TEST_F(FileTest, invalid_return) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001086 std::string policy =
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001087 "read:arg0 == 0; ;";
1088
Zi Lin171ee1e2021-10-13 03:12:18 +00001089 FILE* policy_file = write_to_pipe(policy);
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001090 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001091 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1092 &labels_);
Luis Hector Chavez52f3dd72017-09-01 19:14:22 -07001093 fclose(policy_file);
1094
1095 /*
1096 * Policy is malformed, but process should not crash.
1097 */
1098 ASSERT_EQ(res, -1);
1099}
1100
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001101TEST_F(FileTest, seccomp_mode1) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001102 std::string policy =
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001103 "read: 1\n"
1104 "write: 1\n"
1105 "rt_sigreturn: 1\n"
1106 "exit: 1\n";
1107
Zi Lin171ee1e2021-10-13 03:12:18 +00001108 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001109 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001110 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1111 &labels_);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001112 fclose(policy_file);
1113
1114 /*
1115 * Checks return value and that the blocks only allow expected syscalls.
1116 */
1117 ASSERT_EQ(res, 0);
1118 struct filter_block *curr_block = head_;
1119 ASSERT_NE(curr_block, nullptr);
1120 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_read);
1121 curr_block = curr_block->next;
1122 ASSERT_NE(curr_block, nullptr);
1123 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_write);
1124 curr_block = curr_block->next;
1125 ASSERT_NE(curr_block, nullptr);
1126 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_rt_sigreturn);
1127 curr_block = curr_block->next;
1128 ASSERT_NE(curr_block, nullptr);
1129 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_exit);
1130
1131 EXPECT_EQ(curr_block->next, nullptr);
1132}
1133
1134TEST_F(FileTest, seccomp_read) {
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001135 std::string policy =
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001136 "read: arg0 == 0\n"
1137 "write: 1\n"
1138 "rt_sigreturn: 1\n"
1139 "exit: 1\n";
1140
1141 const int LABEL_ID = 0;
1142
Zi Lin171ee1e2021-10-13 03:12:18 +00001143 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001144 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001145 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1146 &labels_);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001147 fclose(policy_file);
1148
1149 /*
1150 * Checks return value, that the blocks only allow expected syscalls, and that
1151 * labels between |head_| and |arg_blocks_| match.
1152 */
1153 ASSERT_EQ(res, 0);
1154 struct filter_block *curr_block = head_;
1155 ASSERT_NE(curr_block, nullptr);
1156 EXPECT_ALLOW_SYSCALL_ARGS(curr_block->instrs,
1157 __NR_read,
1158 LABEL_ID,
1159 JUMP_JT,
1160 JUMP_JF);
1161 curr_block = curr_block->next;
1162 ASSERT_NE(curr_block, nullptr);
1163 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_write);
1164 curr_block = curr_block->next;
1165 ASSERT_NE(curr_block, nullptr);
1166 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_rt_sigreturn);
1167 curr_block = curr_block->next;
1168 ASSERT_NE(curr_block, nullptr);
1169 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_exit);
1170
1171 ASSERT_NE(arg_blocks_, nullptr);
1172 size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
1173 EXPECT_EQ(arg_blocks_->total_len, exp_total_len);
1174
1175 /* First block is a label. */
1176 curr_block = arg_blocks_;
1177 ASSERT_NE(curr_block, nullptr);
1178 EXPECT_EQ(curr_block->len, 1U);
1179 EXPECT_ACTUAL_LBL(curr_block->instrs, LABEL_ID);
1180
1181 /* Second block is a comparison. */
1182 curr_block = curr_block->next;
1183 EXPECT_COMP(curr_block);
1184
1185 /* Third block is a jump and a label (end of AND group). */
1186 curr_block = curr_block->next;
1187 ASSERT_NE(curr_block, nullptr);
1188 EXPECT_GROUP_END(curr_block);
1189
1190 /* Fourth block is SECCOMP_RET_KILL. */
1191 curr_block = curr_block->next;
1192 ASSERT_NE(curr_block, nullptr);
1193 EXPECT_KILL(curr_block);
1194
1195 /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
1196 curr_block = curr_block->next;
1197 ASSERT_NE(curr_block, nullptr);
1198 EXPECT_ALLOW(curr_block);
1199
1200 EXPECT_EQ(curr_block->next, nullptr);
1201}
1202
Mike Frysinger29c72342019-03-15 01:39:31 -04001203TEST_F(FileTest, multiline) {
1204 std::string policy =
1205 "read:\\\n1\n"
Mike Frysingere4c69652019-06-26 04:33:17 -04001206 "openat:arg0 \\\nin\\\n \\\n5";
Mike Frysinger29c72342019-03-15 01:39:31 -04001207
1208 const int LABEL_ID = 0;
1209
Zi Lin171ee1e2021-10-13 03:12:18 +00001210 FILE* policy_file = write_to_pipe(policy);
Mike Frysinger29c72342019-03-15 01:39:31 -04001211 ASSERT_NE(policy_file, nullptr);
1212 int res = test_compile_file("policy", policy_file, head_, &arg_blocks_,
1213 &labels_);
1214 fclose(policy_file);
1215
1216 /*
1217 * Policy should be valid.
1218 */
1219 ASSERT_EQ(res, 0);
1220
1221 /* First block is the read. */
1222 struct filter_block *curr_block = head_;
1223 ASSERT_NE(curr_block, nullptr);
1224 EXPECT_ALLOW_SYSCALL(curr_block->instrs, __NR_read);
1225
1226 /* Second block is the open. */
1227 curr_block = curr_block->next;
1228 ASSERT_NE(curr_block, nullptr);
1229 EXPECT_ALLOW_SYSCALL_ARGS(curr_block->instrs,
1230 __NR_openat,
1231 LABEL_ID,
1232 JUMP_JT,
1233 JUMP_JF);
1234
1235 EXPECT_EQ(curr_block->next, nullptr);
1236}
1237
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001238TEST(FilterTest, seccomp_mode1) {
1239 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001240 std::string policy =
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001241 "read: 1\n"
1242 "write: 1\n"
1243 "rt_sigreturn: 1\n"
1244 "exit: 1\n";
1245
Zi Lin171ee1e2021-10-13 03:12:18 +00001246 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001247 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001248
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001249 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001250 fclose(policy_file);
1251
1252 /*
1253 * Checks return value, filter length, and that the filter
1254 * validates arch, loads syscall number, and
1255 * only allows expected syscalls.
1256 */
1257 ASSERT_EQ(res, 0);
1258 EXPECT_EQ(actual.len, 13);
1259 EXPECT_ARCH_VALIDATION(actual.filter);
1260 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1261 BPF_LD + BPF_W + BPF_ABS,
1262 syscall_nr);
1263 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read);
1264 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3, __NR_write);
1265 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1266 __NR_rt_sigreturn);
1267 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit);
1268 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9,
1269 BPF_RET + BPF_K,
1270 SECCOMP_RET_KILL);
1271
1272 free(actual.filter);
1273}
1274
Nicole Anderson-Auaba39462020-11-09 23:36:56 +00001275TEST(FilterTest, seccomp_mode1_with_check) {
1276 struct sock_fprog actual;
1277 std::string policy =
1278 "read: 1\n"
1279 "write: 1\n"
1280 "rt_sigreturn: 1\n"
1281 "exit: 1\n";
1282
Zi Lin171ee1e2021-10-13 03:12:18 +00001283 FILE* policy_file = write_to_pipe(policy);
Nicole Anderson-Auaba39462020-11-09 23:36:56 +00001284 ASSERT_NE(policy_file, nullptr);
1285
1286 int res = test_compile_filter("policy", policy_file, &actual,
1287 ACTION_RET_KILL, NO_LOGGING, false
1288 /* allow duplicate syscalls */);
1289 fclose(policy_file);
1290
1291 /*
1292 * Checks return value, filter length, and that the filter
1293 * validates arch, loads syscall number, and
1294 * only allows expected syscalls.
1295 */
1296 ASSERT_EQ(res, 0);
1297 EXPECT_EQ(actual.len, 13);
1298 EXPECT_ARCH_VALIDATION(actual.filter);
1299 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1300 BPF_LD + BPF_W + BPF_ABS,
1301 syscall_nr);
1302 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read);
1303 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3, __NR_write);
1304 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1305 __NR_rt_sigreturn);
1306 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit);
1307 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9,
1308 BPF_RET + BPF_K,
1309 SECCOMP_RET_KILL);
1310
1311 free(actual.filter);
1312}
1313
1314/*
1315 * This fails even with allow_duplicate_syscalls set to true because the
1316 * creation of labels for the arguments causes conflicts which cause the
1317 * compile_filter function to fail.
1318 */
1319TEST(FilterTest, duplicate_read_with_args) {
1320 struct sock_fprog actual;
1321 std::string policy =
1322 "read: arg0 == 0\n"
1323 "read: arg1 == 1\n"
1324 "write: 1\n"
1325 "rt_sigreturn: 1\n"
1326 "exit: 1\n";
1327
Zi Lin171ee1e2021-10-13 03:12:18 +00001328 FILE* policy_file = write_to_pipe(policy);
Nicole Anderson-Auaba39462020-11-09 23:36:56 +00001329 ASSERT_NE(policy_file, nullptr);
1330 int res = test_compile_filter("policy", policy_file, &actual);
1331 fclose(policy_file);
1332
1333 ASSERT_EQ(res, -1);
1334}
1335
1336/*
1337 * This does not fail because only one instance of read defines an argument.
1338 */
1339TEST(FilterTest, duplicate_read_with_one_arg) {
1340 struct sock_fprog actual;
1341 std::string policy =
1342 "read: arg0 == 0\n"
1343 "read: 1\n"
1344 "write: 1\n"
1345 "rt_sigreturn: 1\n"
1346 "exit: 1\n";
1347
Zi Lin171ee1e2021-10-13 03:12:18 +00001348 FILE* policy_file = write_to_pipe(policy);
Nicole Anderson-Auaba39462020-11-09 23:36:56 +00001349 ASSERT_NE(policy_file, nullptr);
1350 int res = test_compile_filter("policy", policy_file, &actual);
1351 fclose(policy_file);
1352
1353 /* TODO: Don't know how to generate a correct value to validate the filter
1354 * that is generated. */
1355 ASSERT_EQ(res, 0);
1356 free(actual.filter);
1357}
1358
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001359TEST(FilterTest, seccomp_mode1_trap) {
1360 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001361 std::string policy =
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001362 "read: 1\n"
1363 "write: 1\n"
1364 "rt_sigreturn: 1\n"
1365 "exit: 1\n";
1366
Zi Lin171ee1e2021-10-13 03:12:18 +00001367 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001368 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001369
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001370 int res =
1371 test_compile_filter("policy", policy_file, &actual, ACTION_RET_TRAP);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001372 fclose(policy_file);
1373
1374 /*
1375 * Checks return value, filter length, and that the filter
1376 * validates arch, loads syscall number, and
1377 * only allows expected syscalls.
1378 */
1379 ASSERT_EQ(res, 0);
1380 EXPECT_EQ(actual.len, 13);
1381 EXPECT_ARCH_VALIDATION(actual.filter);
1382 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1383 BPF_LD+BPF_W+BPF_ABS, syscall_nr);
1384 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1,
1385 __NR_read);
1386 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3,
1387 __NR_write);
1388 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1389 __NR_rt_sigreturn);
1390 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
1391 __NR_exit);
1392 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
1393 SECCOMP_RET_TRAP);
1394
1395 free(actual.filter);
1396}
1397
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001398TEST(FilterTest, seccomp_mode1_log) {
1399 struct sock_fprog actual;
1400 std::string policy =
1401 "read: 1\n"
1402 "write: 1\n"
1403 "rt_sigreturn: 1\n"
1404 "exit: 1\n";
1405
Zi Lin171ee1e2021-10-13 03:12:18 +00001406 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001407 ASSERT_NE(policy_file, nullptr);
1408
1409 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_LOG,
1410 USE_RET_LOG_LOGGING);
1411 fclose(policy_file);
1412
1413 /*
1414 * Checks return value, filter length, and that the filter
1415 * validates arch, loads syscall number, and
1416 * only allows expected syscalls.
1417 */
1418 ASSERT_EQ(res, 0);
1419 EXPECT_EQ(actual.len, 13);
1420 EXPECT_ARCH_VALIDATION(actual.filter);
1421 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1422 BPF_LD+BPF_W+BPF_ABS, syscall_nr);
1423 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1,
1424 __NR_read);
1425 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3,
1426 __NR_write);
1427 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1428 __NR_rt_sigreturn);
1429 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
1430 __NR_exit);
1431 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
1432 SECCOMP_RET_LOG);
1433
1434 free(actual.filter);
1435}
1436
1437TEST(FilterTest, seccomp_mode1_log_fails) {
1438 struct sock_fprog actual;
1439 std::string policy =
1440 "read: 1\n"
1441 "write: 1\n"
1442 "rt_sigreturn: 1\n"
1443 "exit: 1\n";
1444
Zi Lin171ee1e2021-10-13 03:12:18 +00001445 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001446 ASSERT_NE(policy_file, nullptr);
1447
1448 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_LOG,
1449 NO_LOGGING);
1450 fclose(policy_file);
1451
1452 /*
1453 * ACTION_RET_LOG should never be used without allowing logging.
1454 */
1455 ASSERT_EQ(res, -1);
1456}
1457
Jorge Lucangeli Obesd23ad792020-10-13 10:26:40 -04001458TEST(FilterTest, seccomp_mode1_ret_kill_process) {
1459 struct sock_fprog actual;
1460 std::string policy =
1461 "read: 1\n"
1462 "write: 1\n"
1463 "rt_sigreturn: 1\n"
1464 "exit: 1\n";
1465
Zi Lin171ee1e2021-10-13 03:12:18 +00001466 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obesd23ad792020-10-13 10:26:40 -04001467 ASSERT_NE(policy_file, nullptr);
1468
1469 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_KILL_PROCESS,
1470 NO_LOGGING);
1471 fclose(policy_file);
1472
1473 /*
1474 * Checks return value, filter length, and that the filter
1475 * validates arch, loads syscall number, and
1476 * only allows expected syscalls.
1477 */
1478 ASSERT_EQ(res, 0);
1479 EXPECT_EQ(actual.len, 13);
1480 EXPECT_ARCH_VALIDATION(actual.filter);
1481 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1482 BPF_LD+BPF_W+BPF_ABS, syscall_nr);
1483 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1,
1484 __NR_read);
1485 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3,
1486 __NR_write);
1487 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1488 __NR_rt_sigreturn);
1489 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
1490 __NR_exit);
1491 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
1492 SECCOMP_RET_KILL_PROCESS);
1493
1494 free(actual.filter);
1495}
1496
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001497TEST(FilterTest, seccomp_read_write) {
1498 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001499 std::string policy =
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001500 "read: arg0 == 0\n"
1501 "write: arg0 == 1 || arg0 == 2\n"
1502 "rt_sigreturn: 1\n"
1503 "exit: 1\n";
1504
Zi Lin171ee1e2021-10-13 03:12:18 +00001505 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001506 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001507
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001508 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001509 fclose(policy_file);
1510
1511 /*
1512 * Checks return value, filter length, and that the filter
1513 * validates arch, loads syscall number, and
1514 * only allows expected syscalls, jumping to correct arg filter
1515 * offsets.
1516 */
1517 ASSERT_EQ(res, 0);
1518 size_t exp_total_len = 27 + 3 * (BPF_ARG_COMP_LEN + 1);
1519 EXPECT_EQ(actual.len, exp_total_len);
1520
1521 EXPECT_ARCH_VALIDATION(actual.filter);
1522 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1523 BPF_LD + BPF_W + BPF_ABS,
1524 syscall_nr);
1525 EXPECT_ALLOW_SYSCALL_ARGS(
1526 actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read, 7, 0, 0);
1527 EXPECT_ALLOW_SYSCALL_ARGS(actual.filter + ARCH_VALIDATION_LEN + 3,
1528 __NR_write,
1529 12 + BPF_ARG_COMP_LEN,
1530 0,
1531 0);
1532 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
1533 __NR_rt_sigreturn);
1534 EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit);
1535 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9,
1536 BPF_RET + BPF_K,
1537 SECCOMP_RET_KILL);
1538
1539 free(actual.filter);
1540}
1541
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001542TEST(FilterTest, misplaced_whitespace) {
1543 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001544 std::string policy = "read :1\n";
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001545
Zi Lin171ee1e2021-10-13 03:12:18 +00001546 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001547 ASSERT_NE(policy_file, nullptr);
1548
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001549 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesc4992572017-04-28 10:49:01 -04001550 fclose(policy_file);
1551
1552 /* Checks return value and filter length. */
1553 ASSERT_EQ(res, 0);
1554 EXPECT_EQ(actual.len,
1555 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ + ALLOW_SYSCALL_LEN +
1556 1 /* ret kill */);
1557 free(actual.filter);
1558}
1559
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001560TEST(FilterTest, missing_atom) {
1561 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001562 std::string policy = "open:\n";
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001563
Zi Lin171ee1e2021-10-13 03:12:18 +00001564 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001565 ASSERT_NE(policy_file, nullptr);
1566
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001567 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001568 fclose(policy_file);
1569 ASSERT_NE(res, 0);
1570}
1571
1572TEST(FilterTest, whitespace_atom) {
1573 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001574 std::string policy = "open:\t \n";
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001575
Zi Lin171ee1e2021-10-13 03:12:18 +00001576 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obes45932a52017-03-15 17:02:58 -04001577 ASSERT_NE(policy_file, nullptr);
1578
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001579 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes1a122b82016-11-01 11:59:33 -04001580 fclose(policy_file);
1581 ASSERT_NE(res, 0);
1582}
1583
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001584TEST(FilterTest, invalid_name) {
1585 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001586 std::string policy = "notasyscall: 1\n";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001587
Zi Lin171ee1e2021-10-13 03:12:18 +00001588 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001589 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001590
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001591 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001592 fclose(policy_file);
1593 ASSERT_NE(res, 0);
1594}
1595
1596TEST(FilterTest, invalid_arg) {
1597 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001598 std::string policy = "open: argnn ==\n";
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001599
Zi Lin171ee1e2021-10-13 03:12:18 +00001600 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001601 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001602
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001603 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001604 fclose(policy_file);
1605 ASSERT_NE(res, 0);
1606}
1607
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001608TEST(FilterTest, invalid_tokens) {
1609 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001610 std::string policy = "read: arg0 == 1 |||| arg0 == 2\n";
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001611
Zi Lin171ee1e2021-10-13 03:12:18 +00001612 FILE* policy_file = write_to_pipe(policy);
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001613 ASSERT_NE(policy_file, nullptr);
1614
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001615 int res = test_compile_filter("policy", policy_file, &actual);
Mike Frysingerb4c7e772018-01-17 17:40:15 -05001616 fclose(policy_file);
1617 ASSERT_NE(res, 0);
1618}
1619
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001620TEST(FilterTest, nonexistent) {
1621 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001622 int res = test_compile_filter("policy", nullptr, &actual);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001623 ASSERT_NE(res, 0);
1624}
1625
1626TEST(FilterTest, log) {
1627 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001628 std::string policy =
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001629 "read: 1\n"
1630 "write: 1\n"
1631 "rt_sigreturn: 1\n"
1632 "exit: 1\n";
1633
Zi Lin171ee1e2021-10-13 03:12:18 +00001634 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001635 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001636
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001637 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_TRAP,
1638 USE_SIGSYS_LOGGING);
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001639 fclose(policy_file);
1640
1641 size_t i;
1642 size_t index = 0;
1643 /*
1644 * Checks return value, filter length, and that the filter
1645 * validates arch, loads syscall number, only allows expected syscalls,
1646 * and returns TRAP on failure.
1647 * NOTE(jorgelo): the filter is longer since we add the syscalls needed
1648 * for logging.
1649 */
1650 ASSERT_EQ(res, 0);
1651 EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len);
1652 EXPECT_ARCH_VALIDATION(actual.filter);
1653 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1654 BPF_LD + BPF_W + BPF_ABS,
1655 syscall_nr);
1656
1657 index = ARCH_VALIDATION_LEN + 1;
1658 for (i = 0; i < log_syscalls_len; i++)
1659 EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i),
Nicole Anderson-Aubcc8cfd2020-11-10 20:33:27 +00001660 lookup_syscall(log_syscalls[i], NULL));
Jorge Lucangeli Obes106d97f2016-08-19 12:34:02 -04001661
1662 index += 2 * log_syscalls_len;
1663
1664 EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read);
1665 EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write);
1666 EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn);
1667 EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit);
1668 EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET + BPF_K, SECCOMP_RET_TRAP);
1669
1670 free(actual.filter);
1671}
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001672
1673TEST(FilterTest, allow_log_but_kill) {
1674 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001675 std::string policy =
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001676 "read: 1\n"
1677 "write: 1\n"
1678 "rt_sigreturn: 1\n"
1679 "exit: 1\n";
1680
Zi Lin171ee1e2021-10-13 03:12:18 +00001681 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -04001682 ASSERT_NE(policy_file, nullptr);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001683
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001684 int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_KILL,
1685 USE_SIGSYS_LOGGING);
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001686 fclose(policy_file);
1687
1688 size_t i;
1689 size_t index = 0;
1690 /*
1691 * Checks return value, filter length, and that the filter
1692 * validates arch, loads syscall number, only allows expected syscalls,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001693 * and kills on failure.
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001694 * NOTE(jorgelo): the filter is longer since we add the syscalls needed
1695 * for logging.
1696 */
1697 ASSERT_EQ(res, 0);
1698 EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len);
1699 EXPECT_ARCH_VALIDATION(actual.filter);
1700 EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
1701 BPF_LD+BPF_W+BPF_ABS, syscall_nr);
1702
1703 index = ARCH_VALIDATION_LEN + 1;
1704 for (i = 0; i < log_syscalls_len; i++)
1705 EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i),
Nicole Anderson-Aubcc8cfd2020-11-10 20:33:27 +00001706 lookup_syscall(log_syscalls[i], NULL));
Jorge Lucangeli Obes713f6fb2016-10-03 13:03:25 -04001707
1708 index += 2 * log_syscalls_len;
1709
1710 EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read);
1711 EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write);
1712 EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn);
1713 EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit);
1714 EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET+BPF_K,
1715 SECCOMP_RET_KILL);
1716
1717 free(actual.filter);
1718}
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001719
Matt Delcob1b2eba2020-01-10 12:03:27 -08001720TEST(FilterTest, frequency) {
1721 struct sock_fprog actual;
1722 std::string frequency = "@frequency ./path/is/ignored.frequency\n";
1723
Zi Lin171ee1e2021-10-13 03:12:18 +00001724 FILE* policy_file = write_to_pipe(frequency);
Matt Delcob1b2eba2020-01-10 12:03:27 -08001725 ASSERT_NE(policy_file, nullptr);
1726 int res = test_compile_filter("policy", policy_file, &actual);
1727 fclose(policy_file);
1728 EXPECT_EQ(res, 0);
Jorge Lucangeli Obesdf7a49b2020-11-03 11:26:42 -05001729
1730 free(actual.filter);
Matt Delcob1b2eba2020-01-10 12:03:27 -08001731}
1732
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001733TEST(FilterTest, include_invalid_token) {
1734 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001735 std::string invalid_token = "@unclude ./test/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001736
Zi Lin171ee1e2021-10-13 03:12:18 +00001737 FILE* policy_file = write_to_pipe(invalid_token);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001738 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001739 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001740 fclose(policy_file);
1741 EXPECT_NE(res, 0);
1742}
1743
1744TEST(FilterTest, include_no_space) {
1745 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001746 std::string no_space = "@includetest/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001747
Zi Lin171ee1e2021-10-13 03:12:18 +00001748 FILE* policy_file = write_to_pipe(no_space);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001749 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001750 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001751 fclose(policy_file);
1752 EXPECT_NE(res, 0);
1753}
1754
1755TEST(FilterTest, include_double_token) {
1756 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001757 std::string double_token = "@includeinclude ./test/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001758
Zi Lin171ee1e2021-10-13 03:12:18 +00001759 FILE* policy_file = write_to_pipe(double_token);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001760 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001761 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001762 fclose(policy_file);
1763 EXPECT_NE(res, 0);
1764}
1765
1766TEST(FilterTest, include_no_file) {
1767 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001768 std::string no_file = "@include\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001769
Zi Lin171ee1e2021-10-13 03:12:18 +00001770 FILE* policy_file = write_to_pipe(no_file);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001771 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001772 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001773 fclose(policy_file);
1774 EXPECT_NE(res, 0);
1775}
1776
1777TEST(FilterTest, include_space_no_file) {
1778 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001779 std::string space_no_file = "@include \n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001780
Zi Lin171ee1e2021-10-13 03:12:18 +00001781 FILE* policy_file = write_to_pipe(space_no_file);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001782 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001783 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001784 fclose(policy_file);
1785 EXPECT_NE(res, 0);
1786}
1787
1788TEST(FilterTest, include_implicit_relative_path) {
1789 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001790 std::string implicit_relative_path = "@include test/seccomp.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001791
Zi Lin171ee1e2021-10-13 03:12:18 +00001792 FILE* policy_file = write_to_pipe(implicit_relative_path);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001793 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001794 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001795 fclose(policy_file);
1796 EXPECT_NE(res, 0);
1797}
1798
1799TEST(FilterTest, include_extra_text) {
1800 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001801 std::string extra_text = "@include /some/file: sneaky comment\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001802
Zi Lin171ee1e2021-10-13 03:12:18 +00001803 FILE* policy_file = write_to_pipe(extra_text);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001804 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001805 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001806 fclose(policy_file);
1807 EXPECT_NE(res, 0);
1808}
1809
1810TEST(FilterTest, include_split_filename) {
1811 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001812 std::string split_filename = "@include /some/file:colon.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001813
Zi Lin171ee1e2021-10-13 03:12:18 +00001814 FILE* policy_file = write_to_pipe(split_filename);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001815 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001816 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001817 fclose(policy_file);
1818 EXPECT_NE(res, 0);
1819}
1820
1821TEST(FilterTest, include_nonexistent_file) {
1822 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001823 std::string include_policy = "@include ./nonexistent.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001824
Zi Lin171ee1e2021-10-13 03:12:18 +00001825 FILE* policy_file = write_to_pipe(include_policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001826 ASSERT_NE(policy_file, nullptr);
1827
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001828 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001829 fclose(policy_file);
1830
1831 ASSERT_NE(res, 0);
1832}
1833
1834// TODO(jorgelo): Android unit tests don't currently support data files.
1835// Re-enable by creating a temporary policy file at runtime.
1836#if !defined(__ANDROID__)
1837
1838TEST(FilterTest, include) {
1839 struct sock_fprog compiled_plain;
1840 struct sock_fprog compiled_with_include;
1841
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001842 std::string policy_plain =
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001843 "read: 1\n"
1844 "write: 1\n"
1845 "rt_sigreturn: 1\n"
1846 "exit: 1\n";
1847
Zi Lin171ee1e2021-10-13 03:12:18 +00001848 FILE* file_plain = write_to_pipe(policy_plain);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001849 ASSERT_NE(file_plain, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001850 int res_plain = test_compile_filter("policy", file_plain, &compiled_plain,
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001851 ACTION_RET_KILL);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001852 fclose(file_plain);
1853
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001854 std::string policy_with_include =
1855 "@include " + source_path("test/seccomp.policy") + "\n";
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001856
Zi Lin171ee1e2021-10-13 03:12:18 +00001857 FILE* file_with_include = write_to_pipe(policy_with_include);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001858 ASSERT_NE(file_with_include, nullptr);
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -04001859 int res_with_include = test_compile_filter(
1860 "policy", file_with_include, &compiled_with_include, ACTION_RET_KILL);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001861 fclose(file_with_include);
1862
1863 /*
1864 * Checks that filter length is the same for a plain policy and an equivalent
1865 * policy with an @include statement. Also checks that the filter generated
1866 * from the policy with an @include statement is exactly the same as one
1867 * generated from a plain policy.
1868 */
1869 ASSERT_EQ(res_plain, 0);
1870 ASSERT_EQ(res_with_include, 0);
1871
1872 EXPECT_EQ(compiled_plain.len, 13);
1873 EXPECT_EQ(compiled_with_include.len, 13);
1874
1875 EXPECT_ARCH_VALIDATION(compiled_with_include.filter);
1876 EXPECT_EQ_STMT(compiled_with_include.filter + ARCH_VALIDATION_LEN,
1877 BPF_LD + BPF_W + BPF_ABS,
1878 syscall_nr);
1879 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 1,
1880 __NR_read);
1881 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 3,
1882 __NR_write);
1883 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 5,
1884 __NR_rt_sigreturn);
1885 EXPECT_ALLOW_SYSCALL(compiled_with_include.filter + ARCH_VALIDATION_LEN + 7,
1886 __NR_exit);
1887 EXPECT_EQ_STMT(compiled_with_include.filter + ARCH_VALIDATION_LEN + 9,
1888 BPF_RET + BPF_K,
1889 SECCOMP_RET_KILL);
1890
1891 free(compiled_plain.filter);
1892 free(compiled_with_include.filter);
1893}
1894
1895TEST(FilterTest, include_same_syscalls) {
1896 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001897 std::string policy =
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001898 "read: 1\n"
1899 "write: 1\n"
1900 "rt_sigreturn: 1\n"
1901 "exit: 1\n"
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001902 "@include " + source_path("test/seccomp.policy") + "\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001903
Zi Lin171ee1e2021-10-13 03:12:18 +00001904 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001905 ASSERT_NE(policy_file, nullptr);
1906
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001907 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001908 fclose(policy_file);
1909
1910 ASSERT_EQ(res, 0);
1911 EXPECT_EQ(actual.len,
1912 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ +
1913 2 * 8 /* check syscalls twice */ + 1 /* filter return */);
1914 free(actual.filter);
1915}
1916
Nicole Anderson-Auaba39462020-11-09 23:36:56 +00001917TEST(FilterTest, include_same_syscalls_with_check) {
1918 struct sock_fprog actual;
1919 std::string policy =
1920 "read: 1\n"
1921 "write: 1\n"
1922 "rt_sigreturn: 1\n"
1923 "exit: 1\n"
1924 "@include " + source_path("test/seccomp.policy") + "\n";
1925
Zi Lin171ee1e2021-10-13 03:12:18 +00001926 FILE* policy_file = write_to_pipe(policy);
Nicole Anderson-Auaba39462020-11-09 23:36:56 +00001927 ASSERT_NE(policy_file, nullptr);
1928
1929 int res = test_compile_filter("policy", policy_file, &actual,
1930 ACTION_RET_KILL, NO_LOGGING, false
1931 /* allow duplicate syscalls */);
1932 fclose(policy_file);
1933
1934 ASSERT_EQ(res, -1);
1935}
1936
Zach Reiznere9260512019-02-27 18:06:34 -08001937TEST(FilterTest, include_two) {
1938 struct sock_fprog actual;
1939 std::string policy =
1940 "@include " + source_path("test/seccomp.policy") + "\n" +
1941 "@include " + source_path("test/seccomp.policy") + "\n";
1942
Zi Lin171ee1e2021-10-13 03:12:18 +00001943 FILE* policy_file = write_to_pipe(policy);
Zach Reiznere9260512019-02-27 18:06:34 -08001944 ASSERT_NE(policy_file, nullptr);
1945
1946 int res = test_compile_filter("policy", policy_file, &actual);
1947 fclose(policy_file);
1948
1949 ASSERT_EQ(res, 0);
1950 EXPECT_EQ(actual.len,
1951 ARCH_VALIDATION_LEN + 1 /* load syscall nr */ +
1952 2 * 8 /* check syscalls twice */ + 1 /* filter return */);
1953 free(actual.filter);
1954}
1955
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001956TEST(FilterTest, include_invalid_policy) {
1957 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001958 std::string policy =
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001959 "read: 1\n"
1960 "write: 1\n"
1961 "rt_sigreturn: 1\n"
1962 "exit: 1\n"
1963 "@include ./test/invalid_syscall_name.policy\n";
1964
Zi Lin171ee1e2021-10-13 03:12:18 +00001965 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001966 ASSERT_NE(policy_file, nullptr);
1967
1968 /* Ensure the included (invalid) policy file exists. */
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001969 FILE* included_file = fopen(
1970 source_path("test/invalid_syscall_name.policy").c_str(), "re");
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001971 ASSERT_NE(included_file, nullptr);
1972 fclose(included_file);
1973
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001974 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001975 fclose(policy_file);
1976
1977 ASSERT_NE(res, 0);
1978}
1979
1980TEST(FilterTest, include_nested) {
1981 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001982 std::string policy = "@include ./test/nested.policy\n";
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001983
Zi Lin171ee1e2021-10-13 03:12:18 +00001984 FILE* policy_file = write_to_pipe(policy);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001985 ASSERT_NE(policy_file, nullptr);
1986
1987 /* Ensure the policy file exists. */
Mike Frysingerdd5a8842018-08-15 15:57:44 -04001988 FILE* included_file = fopen(source_path("test/nested.policy").c_str(), "re");
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001989 ASSERT_NE(included_file, nullptr);
1990 fclose(included_file);
1991
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04001992 int res = test_compile_filter("policy", policy_file, &actual);
Jorge Lucangeli Obesbce4ccb2017-03-20 13:38:43 -04001993 fclose(policy_file);
1994
1995 ASSERT_NE(res, 0);
1996}
1997
Mike Frysingercdfb0cc2019-03-15 01:39:00 -04001998#endif // !__ANDROID__
1999
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07002000TEST(FilterTest, error_cleanup_leak) {
2001 struct sock_fprog actual;
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04002002 std::string policy =
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07002003 "read:&&\n"
2004 "read:&&";
2005
Zi Lin171ee1e2021-10-13 03:12:18 +00002006 FILE* policy_file = write_to_pipe(policy);
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07002007 ASSERT_NE(policy_file, nullptr);
Mike Frysinger68a1b3b2018-08-15 17:00:18 -04002008 int res = test_compile_filter("policy", policy_file, &actual);
Luis Hector Chavez1a87c8a2017-09-02 13:18:31 -07002009 fclose(policy_file);
2010
2011 /*
2012 * Policy is malformed, but process should not leak.
2013 */
2014 ASSERT_EQ(res, -1);
2015}