1 /* syscall_filter_unittest.c
2  * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  *
6  * Test syscall filtering.
7  */
8 
9 #include <asm/unistd.h>
10 #include <errno.h>
11 #include <fcntl.h>	/* For O_WRONLY */
12 
13 #include "test_harness.h"
14 
15 #include "bpf.h"
16 #include "syscall_filter.h"
17 
18 #include "util.h"
19 
20 /* BPF testing macros. */
21 #define EXPECT_EQ_BLOCK(_block, _code, _k, _jt, _jf)	\
22 do {	\
23 	EXPECT_EQ((_block)->code, _code);		\
24 	EXPECT_EQ((_block)->k, (unsigned int)(_k));	\
25 	EXPECT_EQ((_block)->jt, _jt);			\
26 	EXPECT_EQ((_block)->jf, _jf);			\
27 } while (0)
28 
29 #define EXPECT_EQ_STMT(_block, _code, _k) \
30 	EXPECT_EQ_BLOCK(_block, _code, _k, 0, 0)
31 
32 #define EXPECT_COMP(_block) \
33 do {	\
34 	EXPECT_EQ((_block)->len, BPF_ARG_COMP_LEN + 1);			\
35 	EXPECT_EQ((_block)->instrs->code, BPF_LD+BPF_W+BPF_ABS);	\
36 } while (0)
37 
38 #define EXPECT_LBL(_block) \
39 	do {	\
40 	EXPECT_EQ((_block)->code, BPF_JMP+BPF_JA);	\
41 	EXPECT_EQ((_block)->jt, LABEL_JT);		\
42 	EXPECT_EQ((_block)->jf, LABEL_JF);		\
43 } while (0)
44 
45 #define EXPECT_JUMP_LBL(_block) \
46 do {	\
47 	EXPECT_EQ((_block)->code, BPF_JMP+BPF_JA);	\
48 	EXPECT_EQ((_block)->jt, JUMP_JT);		\
49 	EXPECT_EQ((_block)->jf, JUMP_JF);		\
50 } while (0)
51 
52 #define EXPECT_GROUP_END(_block) \
53 do {	\
54 	EXPECT_EQ((_block)->len, 2U);			\
55 	EXPECT_JUMP_LBL(&(_block)->instrs[0]);		\
56 	EXPECT_LBL(&(_block)->instrs[1]);		\
57 } while (0)
58 
59 #define EXPECT_KILL(_block) \
60 do {	\
61 	EXPECT_EQ((_block)->len, 1U);				\
62 	EXPECT_EQ_STMT(_block->instrs,				\
63 			BPF_RET+BPF_K, SECCOMP_RET_KILL);	\
64 } while (0)
65 
66 #define EXPECT_ALLOW(_block) \
67 do {	\
68 	EXPECT_EQ((_block)->len, 2U);				\
69 	EXPECT_LBL(&(_block)->instrs[0]);			\
70 	EXPECT_EQ_STMT(&(_block)->instrs[1],			\
71 			BPF_RET+BPF_K, SECCOMP_RET_ALLOW);	\
72 } while (0)
73 
74 #define EXPECT_ARCH_VALIDATION(_filter) \
75 do {	\
76 	EXPECT_EQ_STMT(&(_filter)[0], BPF_LD+BPF_W+BPF_ABS, arch_nr);	\
77 	EXPECT_EQ_BLOCK(&(_filter)[1],					\
78 			BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, SKIP, NEXT);	\
79 	EXPECT_EQ_STMT(&(_filter)[2], BPF_RET+BPF_K, SECCOMP_RET_KILL);	\
80 } while (0)
81 
82 #define EXPECT_ALLOW_SYSCALL(_filter, _nr) \
83 do {	\
84 	EXPECT_EQ_BLOCK(&(_filter)[0],					\
85 			BPF_JMP+BPF_JEQ+BPF_K, (_nr), NEXT, SKIP);	\
86 	EXPECT_EQ_STMT(&(_filter)[1],					\
87 			BPF_RET+BPF_K, SECCOMP_RET_ALLOW);		\
88 } while (0)
89 
90 #define EXPECT_ALLOW_SYSCALL_ARGS(_filter, _nr, _id, _jt, _jf) \
91 do {	\
92 	EXPECT_EQ_BLOCK(&(_filter)[0],					\
93 			BPF_JMP+BPF_JEQ+BPF_K, (_nr), NEXT, SKIP);	\
94 	EXPECT_EQ_BLOCK(&(_filter)[1],					\
95 			BPF_JMP+BPF_JA, (_id), (_jt), (_jf));		\
96 } while (0)
97 
98 
FIXTURE(bpf)99 FIXTURE(bpf) {};
100 
FIXTURE_SETUP(bpf)101 FIXTURE_SETUP(bpf) {}
FIXTURE_TEARDOWN(bpf)102 FIXTURE_TEARDOWN(bpf) {}
103 
104 /* Test that setting one BPF instruction works. */
TEST_F(bpf,set_bpf_instr)105 TEST_F(bpf, set_bpf_instr) {
106 	struct sock_filter instr;
107 	unsigned char code = BPF_LD+BPF_W+BPF_ABS;
108 	unsigned int k = 4;
109 	unsigned char jt = 1, jf = 2;
110 
111 	size_t len = set_bpf_instr(&instr, code, k, jt, jf);
112 
113 	EXPECT_EQ(len, 1U);
114 	EXPECT_EQ_BLOCK(&instr, code, k, jt, jf);
115 }
116 
TEST_F(bpf,bpf_load_arg)117 TEST_F(bpf, bpf_load_arg) {
118 	struct sock_filter load_arg[BPF_LOAD_ARG_LEN];
119 	int argidx = 1;
120 	size_t len = bpf_load_arg(load_arg, argidx);
121 
122 	EXPECT_EQ(len, BPF_LOAD_ARG_LEN);
123 
124 #if defined(BITS32)
125 	EXPECT_EQ_STMT(&load_arg[0], BPF_LD+BPF_W+BPF_ABS, LO_ARG(argidx));
126 #elif defined(BITS64)
127 	EXPECT_EQ_STMT(&load_arg[0], BPF_LD+BPF_W+BPF_ABS, LO_ARG(argidx));
128 	EXPECT_EQ_STMT(&load_arg[1], BPF_ST, 0);
129 	EXPECT_EQ_STMT(&load_arg[2], BPF_LD+BPF_W+BPF_ABS, HI_ARG(argidx));
130 	EXPECT_EQ_STMT(&load_arg[3], BPF_ST, 1);
131 #endif
132 }
133 
TEST_F(bpf,bpf_comp_jeq)134 TEST_F(bpf, bpf_comp_jeq) {
135 	struct sock_filter comp_jeq[BPF_COMP_LEN];
136 	unsigned long c = 1;
137 	unsigned char jt = 1;
138 	unsigned char jf = 2;
139 
140 	size_t len = bpf_comp_jeq(comp_jeq, c, jt, jf);
141 
142 	EXPECT_EQ(len, BPF_COMP_LEN);
143 
144 #if defined(BITS32)
145 	EXPECT_EQ_BLOCK(&comp_jeq[0],
146 			BPF_JMP+BPF_JEQ+BPF_K, c, jt, jf);
147 #elif defined(BITS64)
148 	EXPECT_EQ_BLOCK(&comp_jeq[0],
149 			BPF_JMP+BPF_JEQ+BPF_K, 0, 0, jf + 2);
150 	EXPECT_EQ_STMT(&comp_jeq[1], BPF_LD+BPF_MEM, 0);
151 	EXPECT_EQ_BLOCK(&comp_jeq[2],
152 			BPF_JMP+BPF_JEQ+BPF_K, c, jt, jf);
153 #endif
154 }
155 
TEST_F(bpf,bpf_comp_jset)156 TEST_F(bpf, bpf_comp_jset) {
157 	struct sock_filter comp_jset[BPF_COMP_LEN];
158 	unsigned long mask = O_WRONLY;
159 	unsigned char jt = 1;
160 	unsigned char jf = 2;
161 
162 	size_t len = bpf_comp_jset(comp_jset, mask, jt, jf);
163 
164 	EXPECT_EQ(len, BPF_COMP_LEN);
165 
166 #if defined(BITS32)
167 	EXPECT_EQ_BLOCK(&comp_jset[0],
168 			BPF_JMP+BPF_JSET+BPF_K, mask, jt, jf);
169 #elif defined(BITS64)
170 	EXPECT_EQ_BLOCK(&comp_jset[0],
171 			BPF_JMP+BPF_JSET+BPF_K, 0, jt + 2, 0);
172 	EXPECT_EQ_STMT(&comp_jset[1], BPF_LD+BPF_MEM, 0);
173 	EXPECT_EQ_BLOCK(&comp_jset[2],
174 			BPF_JMP+BPF_JSET+BPF_K, mask, jt, jf);
175 #endif
176 }
177 
TEST_F(bpf,bpf_arg_comp)178 TEST_F(bpf, bpf_arg_comp) {
179 	struct sock_filter *arg_comp;
180 	int op = EQ;
181 	int argidx = 1;
182 	unsigned long c = 3;
183 	unsigned int label_id = 0;
184 
185 	size_t len = bpf_arg_comp(&arg_comp, op, argidx, c, label_id);
186 
187 	EXPECT_EQ(len, BPF_ARG_COMP_LEN + 1);
188 
189 #if defined(BITS32)
190 	EXPECT_EQ_STMT(&arg_comp[0],
191 			BPF_LD+BPF_W+BPF_ABS, LO_ARG(argidx));
192 	EXPECT_EQ_BLOCK(&arg_comp[1],
193 			BPF_JMP+BPF_JEQ+BPF_K, c, 1, 0);
194 	EXPECT_JUMP_LBL(&arg_comp[2]);
195 #elif defined(BITS64)
196 	EXPECT_EQ_STMT(&arg_comp[0],
197 			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],
200 			BPF_LD+BPF_W+BPF_ABS, HI_ARG(argidx));
201 	EXPECT_EQ_STMT(&arg_comp[3], BPF_ST, 1);
202 
203 	EXPECT_EQ_BLOCK(&arg_comp[4],
204 			BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 2);
205 	EXPECT_EQ_STMT(&arg_comp[5], BPF_LD+BPF_MEM, 0);
206 	EXPECT_EQ_BLOCK(&arg_comp[6],
207 			BPF_JMP+BPF_JEQ+BPF_K, c, 1, 0);
208 	EXPECT_JUMP_LBL(&arg_comp[7]);
209 #endif
210 	free(arg_comp);
211 }
212 
TEST_F(bpf,bpf_validate_arch)213 TEST_F(bpf, bpf_validate_arch) {
214 	struct sock_filter validate_arch[ARCH_VALIDATION_LEN];
215 
216 	size_t len = bpf_validate_arch(validate_arch);
217 
218 	EXPECT_EQ(len, ARCH_VALIDATION_LEN);
219 	EXPECT_ARCH_VALIDATION(validate_arch);
220 }
221 
TEST_F(bpf,bpf_allow_syscall)222 TEST_F(bpf, bpf_allow_syscall) {
223 	struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN];
224 	int nr = 1;
225 
226 	size_t len = bpf_allow_syscall(allow_syscall, nr);
227 
228 	EXPECT_EQ(len, ALLOW_SYSCALL_LEN);
229 	EXPECT_ALLOW_SYSCALL(allow_syscall, nr);
230 }
231 
TEST_F(bpf,bpf_allow_syscall_args)232 TEST_F(bpf, bpf_allow_syscall_args) {
233 	struct sock_filter allow_syscall[ALLOW_SYSCALL_LEN];
234 	int nr = 1;
235 	unsigned int id = 1024;
236 
237 	size_t len = bpf_allow_syscall_args(allow_syscall, nr, id);
238 
239 	EXPECT_EQ(len, ALLOW_SYSCALL_LEN);
240 	EXPECT_ALLOW_SYSCALL_ARGS(allow_syscall, nr, id, JUMP_JT, JUMP_JF);
241 }
242 
FIXTURE(arg_filter)243 FIXTURE(arg_filter) {
244 	struct bpf_labels labels;
245 };
246 
FIXTURE_SETUP(arg_filter)247 FIXTURE_SETUP(arg_filter) {}
FIXTURE_TEARDOWN(arg_filter)248 FIXTURE_TEARDOWN(arg_filter) {}
249 
TEST_F(arg_filter,arg0_equals)250 TEST_F(arg_filter, arg0_equals) {
251 	const char *fragment = "arg0 == 0";
252 	int nr = 1;
253 	unsigned int id = 0;
254 	struct filter_block *block =
255 		compile_section(nr, fragment, id, &self->labels);
256 
257 	ASSERT_NE(block, NULL);
258 	size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
259 	EXPECT_EQ(block->total_len, exp_total_len);
260 
261 	/* First block is a label. */
262 	struct filter_block *curr_block = block;
263 	ASSERT_NE(curr_block, NULL);
264 	EXPECT_EQ(block->len, 1U);
265 	EXPECT_LBL(curr_block->instrs);
266 
267 	/* Second block is a comparison. */
268 	curr_block = block->next;
269 	EXPECT_COMP(curr_block);
270 
271 	/* Third block is a jump and a label (end of AND group). */
272 	curr_block = curr_block->next;
273 	EXPECT_NE(curr_block, NULL);
274 	EXPECT_GROUP_END(curr_block);
275 
276 	/* Fourth block is SECCOMP_RET_KILL */
277 	curr_block = curr_block->next;
278 	EXPECT_NE(curr_block, NULL);
279 	EXPECT_KILL(curr_block);
280 
281 	/* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW */
282 	curr_block = curr_block->next;
283 	EXPECT_NE(curr_block, NULL);
284 	EXPECT_ALLOW(curr_block);
285 
286 	EXPECT_EQ(curr_block->next, NULL);
287 
288 	free_block_list(block);
289 	free_label_strings(&self->labels);
290 }
291 
TEST_F(arg_filter,arg0_mask)292 TEST_F(arg_filter, arg0_mask) {
293 	const char *fragment = "arg1 & O_RDWR";
294 	int nr = 1;
295 	unsigned int id = 0;
296 	struct filter_block *block =
297 		compile_section(nr, fragment, id, &self->labels);
298 
299 	ASSERT_NE(block, NULL);
300 	size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
301 	EXPECT_EQ(block->total_len, exp_total_len);
302 
303 	/* First block is a label. */
304 	struct filter_block *curr_block = block;
305 	ASSERT_NE(curr_block, NULL);
306 	EXPECT_EQ(block->len, 1U);
307 	EXPECT_LBL(curr_block->instrs);
308 
309 	/* Second block is a comparison. */
310 	curr_block = block->next;
311 	EXPECT_COMP(curr_block);
312 
313 	/* Third block is a jump and a label (end of AND group). */
314 	curr_block = curr_block->next;
315 	EXPECT_NE(curr_block, NULL);
316 	EXPECT_GROUP_END(curr_block);
317 
318 	/* Fourth block is SECCOMP_RET_KILL */
319 	curr_block = curr_block->next;
320 	EXPECT_NE(curr_block, NULL);
321 	EXPECT_KILL(curr_block);
322 
323 	/* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW */
324 	curr_block = curr_block->next;
325 	EXPECT_NE(curr_block, NULL);
326 	EXPECT_ALLOW(curr_block);
327 
328 	EXPECT_EQ(curr_block->next, NULL);
329 
330 	free_block_list(block);
331 	free_label_strings(&self->labels);
332 }
333 
TEST_F(arg_filter,arg0_eq_mask)334 TEST_F(arg_filter, arg0_eq_mask) {
335 	const char *fragment = "arg1 == O_WRONLY|O_CREAT";
336 	int nr = 1;
337 	unsigned int id = 0;
338 	struct filter_block *block =
339 		compile_section(nr, fragment, id, &self->labels);
340 
341 	ASSERT_NE(block, NULL);
342 	size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
343 	EXPECT_EQ(block->total_len, exp_total_len);
344 
345 	/* First block is a label. */
346 	struct filter_block *curr_block = block;
347 	ASSERT_NE(curr_block, NULL);
348 	EXPECT_EQ(block->len, 1U);
349 	EXPECT_LBL(curr_block->instrs);
350 
351 	/* Second block is a comparison. */
352 	curr_block = block->next;
353 	EXPECT_COMP(curr_block);
354 	EXPECT_EQ(curr_block->instrs[BPF_ARG_COMP_LEN  - 1].k,
355 		(unsigned int)(O_WRONLY | O_CREAT));
356 
357 	/* Third block is a jump and a label (end of AND group). */
358 	curr_block = curr_block->next;
359 	EXPECT_NE(curr_block, NULL);
360 	EXPECT_GROUP_END(curr_block);
361 
362 	/* Fourth block is SECCOMP_RET_KILL */
363 	curr_block = curr_block->next;
364 	EXPECT_NE(curr_block, NULL);
365 	EXPECT_KILL(curr_block);
366 
367 	/* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW */
368 	curr_block = curr_block->next;
369 	EXPECT_NE(curr_block, NULL);
370 	EXPECT_ALLOW(curr_block);
371 
372 	EXPECT_EQ(curr_block->next, NULL);
373 
374 	free_block_list(block);
375 	free_label_strings(&self->labels);
376 }
377 
TEST_F(arg_filter,and_or)378 TEST_F(arg_filter, and_or) {
379 	const char *fragment = "arg0 == 0 && arg1 == 0 || arg0 == 1";
380 	int nr = 1;
381 	unsigned int id = 0;
382 
383 	struct filter_block *block =
384 		compile_section(nr, fragment, id, &self->labels);
385 	ASSERT_NE(block, NULL);
386 	size_t exp_total_len = 1 + 3 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2;
387 	EXPECT_EQ(block->total_len, exp_total_len);
388 
389 	/* First block is a label. */
390 	struct filter_block *curr_block = block;
391 	ASSERT_NE(curr_block, NULL);
392 	EXPECT_EQ(block->len, 1U);
393 	EXPECT_LBL(curr_block->instrs);
394 
395 	/* Second block is a comparison ("arg0 == 0"). */
396 	curr_block = curr_block->next;
397 	EXPECT_NE(curr_block, NULL);
398 	EXPECT_COMP(curr_block);
399 
400 	/* Third block is a comparison ("arg1 == 0"). */
401 	curr_block = curr_block->next;
402 	EXPECT_NE(curr_block, NULL);
403 	EXPECT_COMP(curr_block);
404 
405 	/* Fourth block is a jump and a label (end of AND group). */
406 	curr_block = curr_block->next;
407 	EXPECT_NE(curr_block, NULL);
408 	EXPECT_GROUP_END(curr_block);
409 
410 	/* Fifth block is a comparison ("arg0 == 1"). */
411 	curr_block = curr_block->next;
412 	EXPECT_NE(curr_block, NULL);
413 	EXPECT_COMP(curr_block);
414 
415 	/* Sixth block is a jump and a label (end of AND group). */
416 	curr_block = curr_block->next;
417 	EXPECT_NE(curr_block, NULL);
418 	EXPECT_GROUP_END(curr_block);
419 
420 	/* Seventh block is SECCOMP_RET_KILL */
421 	curr_block = curr_block->next;
422 	EXPECT_NE(curr_block, NULL);
423 	EXPECT_KILL(curr_block);
424 
425 	/* Eigth block is "SUCCESS" label and SECCOMP_RET_ALLOW */
426 	curr_block = curr_block->next;
427 	EXPECT_NE(curr_block, NULL);
428 	EXPECT_ALLOW(curr_block);
429 
430 	EXPECT_EQ(curr_block->next, NULL);
431 
432 	free_block_list(block);
433 	free_label_strings(&self->labels);
434 }
435 
TEST_F(arg_filter,ret_errno)436 TEST_F(arg_filter, ret_errno) {
437 	const char *fragment = "arg0 == 0 || arg0 == 1; return 1";
438 	int nr = 1;
439 	unsigned int id = 0;
440 
441 	struct filter_block *block =
442 		compile_section(nr, fragment, id, &self->labels);
443 	ASSERT_NE(block, NULL);
444 	size_t exp_total_len = 1 + 2 * (BPF_ARG_COMP_LEN + 1) + 2 + 2 + 1 + 2;
445 	EXPECT_EQ(block->total_len, exp_total_len);
446 
447 	/* First block is a label. */
448 	struct filter_block *curr_block = block;
449 	ASSERT_NE(curr_block, NULL);
450 	EXPECT_EQ(block->len, 1U);
451 	EXPECT_LBL(curr_block->instrs);
452 
453 	/* Second block is a comparison ("arg0 == 0"). */
454 	curr_block = curr_block->next;
455 	EXPECT_NE(curr_block, NULL);
456 	EXPECT_COMP(curr_block);
457 
458 	/* Third block is a jump and a label (end of AND group). */
459 	curr_block = curr_block->next;
460 	EXPECT_NE(curr_block, NULL);
461 	EXPECT_GROUP_END(curr_block);
462 
463 	/* Fourth block is a comparison ("arg0 == 1"). */
464 	curr_block = curr_block->next;
465 	EXPECT_NE(curr_block, NULL);
466 	EXPECT_COMP(curr_block);
467 
468 	/* Fifth block is a jump and a label (end of AND group). */
469 	curr_block = curr_block->next;
470 	EXPECT_NE(curr_block, NULL);
471 	EXPECT_GROUP_END(curr_block);
472 
473 	/* Sixth block is SECCOMP_RET_ERRNO */
474 	curr_block = curr_block->next;
475 	EXPECT_NE(curr_block, NULL);
476 	EXPECT_EQ(curr_block->len, 1U);
477 	EXPECT_EQ_STMT(curr_block->instrs,
478 			BPF_RET+BPF_K,
479 			SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA));
480 
481 	/* Seventh block is "SUCCESS" label and SECCOMP_RET_ALLOW */
482 	curr_block = curr_block->next;
483 	EXPECT_NE(curr_block, NULL);
484 	EXPECT_ALLOW(curr_block);
485 
486 	EXPECT_EQ(curr_block->next, NULL);
487 
488 	free_block_list(block);
489 	free_label_strings(&self->labels);
490 }
491 
TEST_F(arg_filter,unconditional_errno)492 TEST_F(arg_filter, unconditional_errno) {
493 	const char *fragment = "return 1";
494 	int nr = 1;
495 	unsigned int id = 0;
496 
497 	struct filter_block *block =
498 		compile_section(nr, fragment, id, &self->labels);
499 	ASSERT_NE(block, NULL);
500 	size_t exp_total_len = 2;
501 	EXPECT_EQ(block->total_len, exp_total_len);
502 
503 	/* First block is a label. */
504 	struct filter_block *curr_block = block;
505 	ASSERT_NE(curr_block, NULL);
506 	EXPECT_EQ(block->len, 1U);
507 	EXPECT_LBL(curr_block->instrs);
508 
509 	/* Second block is SECCOMP_RET_ERRNO */
510 	curr_block = curr_block->next;
511 	EXPECT_NE(curr_block, NULL);
512 	EXPECT_EQ(curr_block->len, 1U);
513 	EXPECT_EQ_STMT(curr_block->instrs,
514 			BPF_RET+BPF_K,
515 			SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA));
516 
517 	EXPECT_EQ(curr_block->next, NULL);
518 
519 	free_block_list(block);
520 	free_label_strings(&self->labels);
521 }
522 
TEST_F(arg_filter,invalid)523 TEST_F(arg_filter, invalid) {
524 	const char *fragment = "argnn == 0";
525 	int nr = 1;
526 	unsigned int id = 0;
527 
528 	struct filter_block *block =
529 			compile_section(nr, fragment, id, &self->labels);
530 	ASSERT_EQ(block, NULL);
531 
532 	fragment = "arg0 == 0 && arg1 == 1; return errno";
533 	block = compile_section(nr, fragment, id, &self->labels);
534 	ASSERT_EQ(block, NULL);
535 }
536 
FIXTURE(filter)537 FIXTURE(filter) {};
538 
539 /*
540  * When compiling for Android, disable tests that require data files.
541  * TODO(b/259497279): Re-enable this.
542  */
543 #if !defined(__ANDROID__)
FIXTURE_SETUP(filter)544 FIXTURE_SETUP(filter) {}
FIXTURE_TEARDOWN(filter)545 FIXTURE_TEARDOWN(filter) {}
546 
TEST_F(filter,seccomp_mode1)547 TEST_F(filter, seccomp_mode1) {
548 	struct sock_fprog actual;
549 	FILE *policy = fopen("test/seccomp.policy", "r");
550 	int res = compile_filter(policy, &actual, NO_LOGGING);
551 
552 	/*
553 	 * Checks return value, filter length, and that the filter
554 	 * validates arch, loads syscall number, and
555 	 * only allows expected syscalls.
556 	 */
557 	ASSERT_EQ(res, 0);
558 	EXPECT_EQ(actual.len, 13);
559 	EXPECT_ARCH_VALIDATION(actual.filter);
560 	EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
561 			BPF_LD+BPF_W+BPF_ABS, syscall_nr);
562 	EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1,
563 			__NR_read);
564 	EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3,
565 			__NR_write);
566 	EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
567 			__NR_rt_sigreturn);
568 	EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
569 			__NR_exit);
570 	EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
571 			SECCOMP_RET_KILL);
572 
573 	free(actual.filter);
574 	fclose(policy);
575 }
576 
TEST_F(filter,seccomp_read_write)577 TEST_F(filter, seccomp_read_write) {
578 	struct sock_fprog actual;
579 	FILE *policy = fopen("test/stdin_stdout.policy", "r");
580 	int res = compile_filter(policy, &actual, NO_LOGGING);
581 
582 	/*
583 	 * Checks return value, filter length, and that the filter
584 	 * validates arch, loads syscall number, and
585 	 * only allows expected syscalls, jumping to correct arg filter
586 	 * offsets.
587 	 */
588 	ASSERT_EQ(res, 0);
589 	size_t exp_total_len = 27 + 3 * (BPF_ARG_COMP_LEN + 1);
590 	EXPECT_EQ(actual.len, exp_total_len);
591 
592 	EXPECT_ARCH_VALIDATION(actual.filter);
593 	EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
594 			BPF_LD+BPF_W+BPF_ABS, syscall_nr);
595 	EXPECT_ALLOW_SYSCALL_ARGS(actual.filter + ARCH_VALIDATION_LEN + 1,
596 			__NR_read, 7, 0, 0);
597 	EXPECT_ALLOW_SYSCALL_ARGS(actual.filter + ARCH_VALIDATION_LEN + 3,
598 			__NR_write, 12 + BPF_ARG_COMP_LEN, 0, 0);
599 	EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
600 			__NR_rt_sigreturn);
601 	EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
602 			__NR_exit);
603 	EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
604 			SECCOMP_RET_KILL);
605 
606 	free(actual.filter);
607 	fclose(policy);
608 }
609 
TEST_F(filter,invalid)610 TEST_F(filter, invalid) {
611 	struct sock_fprog actual;
612 
613 	FILE *policy = fopen("test/invalid_syscall_name.policy", "r");
614 	int res = compile_filter(policy, &actual, NO_LOGGING);
615 	ASSERT_NE(res, 0);
616 	fclose(policy);
617 
618 	policy = fopen("test/invalid_arg_filter.policy", "r");
619 	res = compile_filter(policy, &actual, NO_LOGGING);
620 	ASSERT_NE(res, 0);
621 	fclose(policy);
622 }
623 
TEST_F(filter,nonexistent)624 TEST_F(filter, nonexistent) {
625 	struct sock_fprog actual;
626 
627 	FILE *policy = fopen("test/nonexistent-file.policy", "r");
628 	int res = compile_filter(policy, &actual, NO_LOGGING);
629 	ASSERT_NE(res, 0);
630 }
631 
TEST_F(filter,log)632 TEST_F(filter, log) {
633 	struct sock_fprog actual;
634 
635 	FILE *policy = fopen("test/seccomp.policy", "r");
636 	int res = compile_filter(policy, &actual, USE_LOGGING);
637 
638 	size_t i;
639 	size_t index = 0;
640 	/*
641 	 * Checks return value, filter length, and that the filter
642 	 * validates arch, loads syscall number, only allows expected syscalls,
643 	 * and returns TRAP on failure.
644 	 * NOTE(jorgelo): the filter is longer since we add the syscalls needed
645 	 * for logging.
646 	 */
647 	ASSERT_EQ(res, 0);
648 	EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len);
649 	EXPECT_ARCH_VALIDATION(actual.filter);
650 	EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
651 			BPF_LD+BPF_W+BPF_ABS, syscall_nr);
652 
653 	index = ARCH_VALIDATION_LEN + 1;
654 	for (i = 0; i < log_syscalls_len; i++)
655 		EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i),
656 				     lookup_syscall(log_syscalls[i]));
657 
658 	index += 2 * log_syscalls_len;
659 
660 	EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read);
661 	EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write);
662 	EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn);
663 	EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit);
664 	EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET+BPF_K,
665 			SECCOMP_RET_TRAP);
666 
667 	free(actual.filter);
668 	fclose(policy);
669 }
670 #endif	/* __ANDROID__ */
671 
672 TEST_HARNESS_MAIN
673