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