Re: [RFC bpf-next v1 7/8] selftests/bpf: allow checking xlated programs in verifier_* tests

Andrii Nakryiko
2024-07-02T00:42:28Z

On Sat, Jun 29, 2024 at 2:48 AM Eduard Zingerman <eddyz87@gmail.com> wrote:
>
> Add a macro __xlated("...") for use with test_loader tests.
>
> When such annotations are present for the test case:
> - bpf_prog_get_info_by_fd() is used to get BPF program after all
> rewrites are applied by verifier.
> - the program is diassembled and patterns specified in __xlated are

typo: google says there is a typo in disassembled

> searched for in the disassembly text.
>
> __xlated matching follows the same mechanics as __msg:
> each subsequent pattern is matched from the point where
> previous pattern ended.
>
> This allows to write tests like below, where the goal is to verify the
> behavior of one of the of the transformations applied by verifier:
>
> SEC("raw_tp")
> __xlated("1: w0 = ")
> __xlated("2: r0 = &(void __percpu *)(r0)")
> __xlated("3: r0 = *(u32 *)(r0 +0)")
> __xlated("4: exit")
> __success __naked void simple(void)
> {
> asm volatile (
> "call %[bpf_get_smp_processor_id];"
> "exit;"
> :
> : __imm(bpf_get_smp_processor_id)
> : __clobber_all);
> }
>
> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> ---
> tools/testing/selftests/bpf/progs/bpf_misc.h | 6 ++
> tools/testing/selftests/bpf/test_loader.c | 80 +++++++++++++++++++-
> 2 files changed, 83 insertions(+), 3 deletions(-)
>

Acked-by: Andrii Nakryiko <andrii@kernel.org>

> diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h
> index 81097a3f15eb..fac131a23578 100644
> --- a/tools/testing/selftests/bpf/progs/bpf_misc.h
> +++ b/tools/testing/selftests/bpf/progs/bpf_misc.h
> @@ -26,6 +26,9 @@
> *
> * __regex Same as __msg, but using a regular expression.
> * __regex_unpriv Same as __msg_unpriv but using a regular expression.
> + * __xlated Expect a line in a disassembly log after verifier applies rewrites.
> + * Multiple __xlated attributes could be specified.
> + * __xlated_unpriv Same as __xlated but for unprivileged mode.
> *
> * __success Expect program load success in privileged mode.
> * __success_unpriv Expect program load success in unprivileged mode.
> @@ -63,11 +66,14 @@
> */
> #define __msg(msg) __attribute__((btf_decl_tag("comment:test_expect_msg=" msg)))
> #define __regex(regex) __attribute__((btf_decl_tag("comment:test_expect_regex=" regex)))
> +#define __xlated(msg) __attribute__((btf_decl_tag("comment:test_expect_xlated=" msg)))
> #define __failure __attribute__((btf_decl_tag("comment:test_expect_failure")))
> #define __success __attribute__((btf_decl_tag("comment:test_expect_success")))
> #define __description(desc) __attribute__((btf_decl_tag("comment:test_description=" desc)))
> #define __msg_unpriv(msg) __attribute__((btf_decl_tag("comment:test_expect_msg_unpriv=" msg)))
> #define __regex_unpriv(regex) __attribute__((btf_decl_tag("comment:test_expect_regex_unpriv=" regex)))
> +#define __xlated_unpriv(msg) \
> + __attribute__((btf_decl_tag("comment:test_expect_xlated_unpriv=" msg)))

nit: keep on a single line? you are ruining the beauty :)

> #define __failure_unpriv __attribute__((btf_decl_tag("comment:test_expect_failure_unpriv")))
> #define __success_unpriv __attribute__((btf_decl_tag("comment:test_expect_success_unpriv")))
> #define __log_level(lvl) __attribute__((btf_decl_tag("comment:test_log_level="#lvl))) …