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);
}
Beispiel #2
0
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);
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);
}
Beispiel #9
0
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;
}