Commit c7665702 authored by David Miller's avatar David Miller Committed by Alexei Starovoitov

bpf: Adjust F_NEEDS_EFFICIENT_UNALIGNED_ACCESS handling in test_verifier.c

Make it set the flag argument to bpf_verify_program() which will relax
the alignment restrictions.

Now all such test cases will go properly through the verifier even on
inefficient unaligned access architectures.

On inefficient unaligned access architectures do not try to run such
programs, instead mark the test case as passing but annotate the
result similarly to how it is done now in the presence of this flag.

So, we get complete full coverage for all REJECT test cases, and at
least verifier level coverage for ACCEPT test cases.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent e9ee9efc
...@@ -14257,13 +14257,14 @@ static int set_admin(bool admin) ...@@ -14257,13 +14257,14 @@ static int set_admin(bool admin)
static void do_test_single(struct bpf_test *test, bool unpriv, static void do_test_single(struct bpf_test *test, bool unpriv,
int *passes, int *errors) int *passes, int *errors)
{ {
int fd_prog, expected_ret, reject_from_alignment; int fd_prog, expected_ret, alignment_prevented_execution;
int prog_len, prog_type = test->prog_type; int prog_len, prog_type = test->prog_type;
struct bpf_insn *prog = test->insns; struct bpf_insn *prog = test->insns;
int map_fds[MAX_NR_MAPS]; int map_fds[MAX_NR_MAPS];
const char *expected_err; const char *expected_err;
uint32_t expected_val; uint32_t expected_val;
uint32_t retval; uint32_t retval;
__u32 pflags;
int i, err; int i, err;
for (i = 0; i < MAX_NR_MAPS; i++) for (i = 0; i < MAX_NR_MAPS; i++)
...@@ -14274,9 +14275,12 @@ static void do_test_single(struct bpf_test *test, bool unpriv, ...@@ -14274,9 +14275,12 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
do_test_fixup(test, prog_type, prog, map_fds); do_test_fixup(test, prog_type, prog, map_fds);
prog_len = probe_filter_length(prog); prog_len = probe_filter_length(prog);
fd_prog = bpf_verify_program(prog_type, prog, prog_len, pflags = 0;
test->flags & F_LOAD_WITH_STRICT_ALIGNMENT ? if (test->flags & F_LOAD_WITH_STRICT_ALIGNMENT)
BPF_F_STRICT_ALIGNMENT : 0, pflags |= BPF_F_STRICT_ALIGNMENT;
if (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS)
pflags |= BPF_F_ANY_ALIGNMENT;
fd_prog = bpf_verify_program(prog_type, prog, prog_len, pflags,
"GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1); "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
expected_ret = unpriv && test->result_unpriv != UNDEF ? expected_ret = unpriv && test->result_unpriv != UNDEF ?
...@@ -14286,28 +14290,27 @@ static void do_test_single(struct bpf_test *test, bool unpriv, ...@@ -14286,28 +14290,27 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
expected_val = unpriv && test->retval_unpriv ? expected_val = unpriv && test->retval_unpriv ?
test->retval_unpriv : test->retval; test->retval_unpriv : test->retval;
reject_from_alignment = fd_prog < 0 && alignment_prevented_execution = 0;
(test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
strstr(bpf_vlog, "misaligned");
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
if (reject_from_alignment) {
printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
strerror(errno));
goto fail_log;
}
#endif
if (expected_ret == ACCEPT) { if (expected_ret == ACCEPT) {
if (fd_prog < 0 && !reject_from_alignment) { if (fd_prog < 0) {
printf("FAIL\nFailed to load prog '%s'!\n", printf("FAIL\nFailed to load prog '%s'!\n",
strerror(errno)); strerror(errno));
goto fail_log; goto fail_log;
} }
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
if (fd_prog >= 0 &&
(test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS)) {
alignment_prevented_execution = 1;
goto test_ok;
}
#endif
} else { } else {
if (fd_prog >= 0) { if (fd_prog >= 0) {
printf("FAIL\nUnexpected success to load!\n"); printf("FAIL\nUnexpected success to load!\n");
goto fail_log; goto fail_log;
} }
if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) { if (!strstr(bpf_vlog, expected_err)) {
printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n", printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n",
expected_err, bpf_vlog); expected_err, bpf_vlog);
goto fail_log; goto fail_log;
...@@ -14335,9 +14338,12 @@ static void do_test_single(struct bpf_test *test, bool unpriv, ...@@ -14335,9 +14338,12 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
goto fail_log; goto fail_log;
} }
} }
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
test_ok:
#endif
(*passes)++; (*passes)++;
printf("OK%s\n", reject_from_alignment ? printf("OK%s\n", alignment_prevented_execution ?
" (NOTE: reject due to unknown alignment)" : ""); " (NOTE: not executed due to unknown alignment)" : "");
close_fds: close_fds:
close(fd_prog); close(fd_prog);
for (i = 0; i < MAX_NR_MAPS; i++) for (i = 0; i < MAX_NR_MAPS; i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment