Re: [PATCH bpf-next v2 1/4] selftests/bpf: map_kptr: expect BPF_ST reject msg on cpuv4 toolchains

Yonghong Song <[email protected]>
Newsgroups org.kernel.vger.bpf
Message-ID <[email protected]>

On 8/7/26 1:44 PM, Vineet Gupta wrote:
> reject_scalar_store_to_kptr stores a scalar constant to a kptr field:
>
>          *(volatile u64 *)&v->unref_ptr = 0xBADC0DE;
>
> Compilers generate one of two encodings for that:
>
>   1. Materialize the constant into a register and emit BPF_STX:
>
>          r1 = 0xbadc0de
>          *(u64 *)(r0 + 0x8) = r1
>
>   2. Or fold it into a single BPF_ST (store immediate):
>
>          *(u64 *)(r0 + 0x8) = 0xbadc0de
>
> These go through different rejection paths and output different
> messages.
>   - BPF_STX goes through map_kptr_match_type(), which prints
>     "invalid kptr access, R...".
>   - BPF_ST only gets the immediate check printing
>     "BPF_ST imm must be 0 when storing to kptr"
>
> The test only expects the BPF_STX message, so it fails on a toolchain
> that folds the constant - bpf-gcc, and clang -mcpu=v4:
>
>    7: (7a) *(u64 *)(r0 +8) = 195936478
>    BPF_ST imm must be 0 when storing to kptr at off=8
>    ...
>    EXPECTED   SUBSTR: 'invalid kptr access, R'
>
> Pick the expected message with __BPF_FEATURE_ST, which clang and bpf-gcc
> both define exactly when BPF_ST codegen is available - cpuv4 for clang,
> and by default for bpf-gcc, whose default cpu is v4.
>
>    bpf-gcc, before: #229/20 map_kptr/reject_scalar_store_to_kptr:FAIL
>    bpf-gcc, after : #229/20 map_kptr/reject_scalar_store_to_kptr:OK
>
> Two caveats worth noting:
>
> - On a BPF_ST toolchain the test now only exercises the imm != 0 check
>    and never reaches map_kptr_match_type(), so the scalar-vs-PTR_TO_BTF_ID
>    rejection the test is named for is only covered by the non-ST builds.
>    The imm path itself is already covered compiler-independently by
>    verifier/map_kptr.c ("map_kptr: BPF_ST imm != 0").
>
> - __BPF_FEATURE_ST says the compiler *can* emit BPF_ST, not that it will.
>    The encoding also depends on the optimization level: clang -mcpu=v4 -O0
>    still emits BPF_STX, which would send the #ifdef down the wrong branch
>    and fail the test. Selftests always build BPF objects at -O2 so this
>    does not bite today, but it is a latent failure mode if that changes.
>
> Signed-off-by: Vineet Gupta <[email protected]>

Acked-by: Yonghong Song <[email protected]>

> ---
>   tools/testing/selftests/bpf/progs/map_kptr_fail.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/progs/map_kptr_fail.c b/tools/testing/selftests/bpf/progs/map_kptr_fail.c
> index f11848dfa78f..5e25ca806060 100644
> --- a/tools/testing/selftests/bpf/progs/map_kptr_fail.c
> +++ b/tools/testing/selftests/bpf/progs/map_kptr_fail.c
> @@ -386,7 +386,16 @@ int kptr_xchg_possibly_null(struct __sk_buff *ctx)
>   }
>   
>   SEC("?tc")
> +/*
> + * A compiler with BPF_ST folds the constant into a store-immediate, which the
> + * verifier rejects on a different path (and with a different message) than the
> + * BPF_STX form.
> + */
> +#ifdef __BPF_FEATURE_ST
> +__failure __msg("BPF_ST imm must be 0 when storing to kptr at off=8")
> +#else
>   __failure __msg("invalid kptr access, R")
> +#endif
>   int reject_scalar_store_to_kptr(struct __sk_buff *ctx)
>   {
>   	struct map_value *v;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.