TEST_F(filter, invalid) { struct sock_fprog actual; FILE *policy = fopen("test/invalid_syscall_name.policy", "r"); int res = compile_filter(policy, &actual, NO_LOGGING, LOG_INFO); ASSERT_NE(res, 0); fclose(policy); policy = fopen("test/invalid_arg_filter.policy", "r"); res = compile_filter(policy, &actual, NO_LOGGING, LOG_INFO); ASSERT_NE(res, 0); fclose(policy); }
int main(int argc, char **argv) { int ret, verbose = 0, c, opt_index, bypass = 0, decimal = 0; char *file = NULL; setfsuid(getuid()); setfsgid(getgid()); if (argc == 1) help(); while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'h': help(); break; case 'v': version(); break; case 'V': verbose = 1; break; case 'D': decimal = 1; break; case 'b': bypass = 1; break; case 'd': bpf_dump_op_table(); die(); case 'i': file = xstrdup(optarg); break; case '?': switch (optopt) { case 'i': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (argc == 2) file = xstrdup(argv[1]); if (!file) panic("No Berkeley Packet Filter program specified!\n"); ret = compile_filter(file, verbose, bypass, decimal); xfree(file); return ret; }
TEST_F(filter, nonexistent) { struct sock_fprog actual; FILE *policy = fopen("test/nonexistent-file.policy", "r"); int res = compile_filter(policy, &actual, NO_LOGGING, LOG_INFO); ASSERT_NE(res, 0); }
TEST_F(filter, seccomp_read_write) { struct sock_fprog actual; FILE *policy = fopen("test/stdin_stdout.policy", "r"); int res = compile_filter(policy, &actual, NO_LOGGING, LOG_INFO); /* * Checks return value, filter length, and that the filter * validates arch, loads syscall number, and * only allows expected syscalls, jumping to correct arg filter * offsets. */ ASSERT_EQ(res, 0); size_t exp_total_len = 27 + 3 * (BPF_ARG_COMP_LEN + 1); EXPECT_EQ(actual.len, exp_total_len); EXPECT_ARCH_VALIDATION(actual.filter); EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, BPF_LD+BPF_W+BPF_ABS, syscall_nr); EXPECT_ALLOW_SYSCALL_ARGS(actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read, 7, 0, 0); EXPECT_ALLOW_SYSCALL_ARGS(actual.filter + ARCH_VALIDATION_LEN + 3, __NR_write, 12 + BPF_ARG_COMP_LEN, 0, 0); EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5, __NR_rt_sigreturn); EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit); EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K, SECCOMP_RET_KILL); free(actual.filter); fclose(policy); }
TEST_F(filter, seccomp_mode1) { struct sock_fprog actual; FILE *policy = fopen("test/seccomp.policy", "r"); int res = compile_filter(policy, &actual, NO_LOGGING, LOG_INFO); /* * Checks return value, filter length, and that the filter * validates arch, loads syscall number, and * only allows expected syscalls. */ ASSERT_EQ(res, 0); EXPECT_EQ(actual.len, 13); EXPECT_ARCH_VALIDATION(actual.filter); EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, BPF_LD+BPF_W+BPF_ABS, syscall_nr); EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1, __NR_read); EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3, __NR_write); EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5, __NR_rt_sigreturn); EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7, __NR_exit); EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K, SECCOMP_RET_KILL); free(actual.filter); fclose(policy); }
int main(int argc, char **argv) { int ret, verbose = 0, c, opt_index; char *file = NULL; if (argc == 1) help(); while (argc > 2 && (c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'h': help(); break; case 'v': version(); break; case 'V': verbose = 1; break; case 'i': file = xstrdup(optarg); break; case '?': switch (optopt) { case 'i': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) whine("Unknown option character " "`0x%X\'!\n", optopt); die(); } default: break; } } if (argc == 2) file = xstrdup(argv[1]); if (!file) panic("No Berkeley Packet Filter program specified!\n"); ret = compile_filter(file, verbose); xfree(file); return ret; }
void API minijail_parse_seccomp_filters(struct minijail *j, const char *path) { FILE *file = fopen(path, "r"); if (!file) { pdie("failed to open seccomp filter file '%s'", path); } struct sock_fprog *fprog = malloc(sizeof(struct sock_fprog)); if (compile_filter(file, fprog, j->flags.log_seccomp_filter)) { die("failed to compile seccomp filter BPF program in '%s'", path); } j->filter_len = fprog->len; j->filter_prog = fprog; fclose(file); }
TEST_F(filter, log) { struct sock_fprog actual; FILE *policy = fopen("test/seccomp.policy", "r"); int res = compile_filter(policy, &actual, USE_LOGGING, LOG_INFO); size_t i; size_t index = 0; /* * Checks return value, filter length, and that the filter * validates arch, loads syscall number, only allows expected syscalls, * and returns TRAP on failure. * NOTE(jorgelo): the filter is longer since we add the syscalls needed * for logging. */ ASSERT_EQ(res, 0); EXPECT_EQ(actual.len, 13 + 2 * log_syscalls_len); EXPECT_ARCH_VALIDATION(actual.filter); EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN, BPF_LD+BPF_W+BPF_ABS, syscall_nr); index = ARCH_VALIDATION_LEN + 1; for (i = 0; i < log_syscalls_len; i++) EXPECT_ALLOW_SYSCALL(actual.filter + (index + 2 * i), lookup_syscall(log_syscalls[i])); index += 2 * log_syscalls_len; EXPECT_ALLOW_SYSCALL(actual.filter + index, __NR_read); EXPECT_ALLOW_SYSCALL(actual.filter + index + 2, __NR_write); EXPECT_ALLOW_SYSCALL(actual.filter + index + 4, __NR_rt_sigreturn); EXPECT_ALLOW_SYSCALL(actual.filter + index + 6, __NR_exit); EXPECT_EQ_STMT(actual.filter + index + 8, BPF_RET+BPF_K, SECCOMP_RET_TRAP); free(actual.filter); fclose(policy); }
int main(int argc, char **argv) { int ret, verbose = 0, c, opt_index, bypass = 0, format = 0; bool invoke_cpp = false; char *file = NULL; setfsuid(getuid()); setfsgid(getgid()); if (argc == 1) help(); while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'h': help(); break; case 'v': version(); break; case 'V': verbose = 1; break; case 'p': invoke_cpp = true; break; case 'f': if (!strncmp(optarg, "C", 1) || !strncmp(optarg, "netsniff-ng", 11)) format = 0; else if (!strncmp(optarg, "tcpdump", 7)) format = 2; else if (!strncmp(optarg, "xt_bpf", 6) || !strncmp(optarg, "tc", 2)) format = 1; else help(); break; case 'b': bypass = 1; break; case 'd': bpf_dump_op_table(); die(); case 'i': file = xstrdup(optarg); break; case '?': switch (optopt) { case 'i': case 'f': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (argc == 2) file = xstrdup(argv[1]); if (!file) panic("No Berkeley Packet Filter program specified!\n"); ret = compile_filter(file, verbose, bypass, format, invoke_cpp); xfree(file); return ret; }