Commit 8c5677f8 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov
Browse files

selftests/bpf: set BPF_F_TEST_SANITY_SCRIPT by default



Make sure to set BPF_F_TEST_SANITY_STRICT program flag by default across
most verifier tests (and a bunch of others that set custom prog flags).

There are currently two tests that do fail validation, if enforced
strictly: verifier_bounds/crossing_64_bit_signed_boundary_2 and
verifier_bounds/crossing_32_bit_signed_boundary_2. To accommodate them,
we teach test_loader a flag negation:

__flag(!<flagname>) will *clear* specified flag, allowing easy opt-out.

We apply __flag(!BPF_F_TEST_SANITY_STRICT) to these to tests.

Also sprinkle BPF_F_TEST_SANITY_STRICT everywhere where we already set
test-only BPF_F_TEST_RND_HI32 flag, for completeness.

Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20231112010609.848406-12-andrii@kernel.org


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent dab16659
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ static int check_load(const char *file, enum bpf_prog_type type)
	}

	bpf_program__set_type(prog, type);
	bpf_program__set_flags(prog, BPF_F_TEST_RND_HI32);
	bpf_program__set_flags(prog, BPF_F_TEST_RND_HI32 | BPF_F_TEST_SANITY_STRICT);
	bpf_program__set_log_level(prog, 4 | extra_prog_load_log_flags);

	err = bpf_object__load(obj);
+2 −0
Original line number Diff line number Diff line
@@ -965,6 +965,7 @@ l0_%=: r0 = 0; \
SEC("xdp")
__description("bound check with JMP_JSLT for crossing 64-bit signed boundary")
__success __retval(0)
__flag(!BPF_F_TEST_SANITY_STRICT) /* known sanity violation */
__naked void crossing_64_bit_signed_boundary_2(void)
{
	asm volatile ("					\
@@ -1046,6 +1047,7 @@ l0_%=: r0 = 0; \
SEC("xdp")
__description("bound check with JMP32_JSLT for crossing 32-bit signed boundary")
__success __retval(0)
__flag(!BPF_F_TEST_SANITY_STRICT) /* known sanity violation */
__naked void crossing_32_bit_signed_boundary_2(void)
{
	asm volatile ("					\
+26 −9
Original line number Diff line number Diff line
@@ -153,6 +153,14 @@ static int parse_retval(const char *str, int *val, const char *name)
	return parse_int(str, val, name);
}

static void update_flags(int *flags, int flag, bool clear)
{
	if (clear)
		*flags &= ~flag;
	else
		*flags |= flag;
}

/* Uses btf_decl_tag attributes to describe the expected test
 * behavior, see bpf_misc.h for detailed description of each attribute
 * and attribute combinations.
@@ -171,6 +179,7 @@ static int parse_test_spec(struct test_loader *tester,
	memset(spec, 0, sizeof(*spec));

	spec->prog_name = bpf_program__name(prog);
	spec->prog_flags = BPF_F_TEST_SANITY_STRICT; /* by default be strict */

	btf = bpf_object__btf(obj);
	if (!btf) {
@@ -187,7 +196,8 @@ static int parse_test_spec(struct test_loader *tester,
	for (i = 1; i < btf__type_cnt(btf); i++) {
		const char *s, *val, *msg;
		const struct btf_type *t;
		int tmp;
		bool clear;
		int flags;

		t = btf__type_by_id(btf, i);
		if (!btf_is_decl_tag(t))
@@ -253,23 +263,30 @@ static int parse_test_spec(struct test_loader *tester,
				goto cleanup;
		} else if (str_has_pfx(s, TEST_TAG_PROG_FLAGS_PFX)) {
			val = s + sizeof(TEST_TAG_PROG_FLAGS_PFX) - 1;

			clear = val[0] == '!';
			if (clear)
				val++;

			if (strcmp(val, "BPF_F_STRICT_ALIGNMENT") == 0) {
				spec->prog_flags |= BPF_F_STRICT_ALIGNMENT;
				update_flags(&spec->prog_flags, BPF_F_STRICT_ALIGNMENT, clear);
			} else if (strcmp(val, "BPF_F_ANY_ALIGNMENT") == 0) {
				spec->prog_flags |= BPF_F_ANY_ALIGNMENT;
				update_flags(&spec->prog_flags, BPF_F_ANY_ALIGNMENT, clear);
			} else if (strcmp(val, "BPF_F_TEST_RND_HI32") == 0) {
				spec->prog_flags |= BPF_F_TEST_RND_HI32;
				update_flags(&spec->prog_flags, BPF_F_TEST_RND_HI32, clear);
			} else if (strcmp(val, "BPF_F_TEST_STATE_FREQ") == 0) {
				spec->prog_flags |= BPF_F_TEST_STATE_FREQ;
				update_flags(&spec->prog_flags, BPF_F_TEST_STATE_FREQ, clear);
			} else if (strcmp(val, "BPF_F_SLEEPABLE") == 0) {
				spec->prog_flags |= BPF_F_SLEEPABLE;
				update_flags(&spec->prog_flags, BPF_F_SLEEPABLE, clear);
			} else if (strcmp(val, "BPF_F_XDP_HAS_FRAGS") == 0) {
				spec->prog_flags |= BPF_F_XDP_HAS_FRAGS;
				update_flags(&spec->prog_flags, BPF_F_XDP_HAS_FRAGS, clear);
			} else if (strcmp(val, "BPF_F_TEST_SANITY_STRICT") == 0) {
				update_flags(&spec->prog_flags, BPF_F_TEST_SANITY_STRICT, clear);
			} else /* assume numeric value */ {
				err = parse_int(val, &tmp, "test prog flags");
				err = parse_int(val, &flags, "test prog flags");
				if (err)
					goto cleanup;
				spec->prog_flags |= tmp;
				update_flags(&spec->prog_flags, flags, clear);
			}
		}
	}
+1 −0
Original line number Diff line number Diff line
@@ -680,6 +680,7 @@ static int load_path(const struct sock_addr_test *test, const char *path)
	bpf_program__set_type(prog, BPF_PROG_TYPE_CGROUP_SOCK_ADDR);
	bpf_program__set_expected_attach_type(prog, test->expected_attach_type);
	bpf_program__set_flags(prog, BPF_F_TEST_RND_HI32);
	bpf_program__set_flags(prog, BPF_F_TEST_SANITY_STRICT);

	err = bpf_object__load(obj);
	if (err) {
+1 −1
Original line number Diff line number Diff line
@@ -1588,7 +1588,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
	if (fixup_skips != skips)
		return;

	pflags = BPF_F_TEST_RND_HI32;
	pflags = BPF_F_TEST_RND_HI32 | BPF_F_TEST_SANITY_STRICT;
	if (test->flags & F_LOAD_WITH_STRICT_ALIGNMENT)
		pflags |= BPF_F_STRICT_ALIGNMENT;
	if (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS)
Loading