From: Yonghong Song <yonghong.song@linux.dev>
To: Vineet Gupta <vineet.gupta@linux.dev>,
bpf@vger.kernel.org, ast@kernel.org,
Eduard Zingerman <eddyz87@gmail.com>,
Andrii Nakryiko <andrii@kernel.org>,
Ihor Solodrai <ihor.solodrai@linux.dev>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [bpf-next 1/4] selftests/bpf: map_kptr: force BPF_STX for the scalar store to kptr
Date: Thu, 6 Aug 2026 10:54:43 -0700 [thread overview]
Message-ID: <e6933505-662f-426b-a781-1243d8dba7f6@linux.dev> (raw)
In-Reply-To: <cfa8641e-2a4d-42f1-8a91-28cbf1478227@linux.dev>
On 8/6/26 9:50 AM, Vineet Gupta wrote:
> On 8/6/26 9:37 AM, Yonghong Song wrote:
>> On 8/5/26 12:25 PM, Vineet Gupta wrote:
>>> On 8/5/26 10:47 AM, Yonghong Song wrote:
>>>> On 8/3/26 10:02 AM, 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
>>>>>
>>>>> check_map_kptr_access() rejects both, but through very different
>>>>> checks.
>>>>> BPF_STX goes through map_kptr_match_type(), whose first test is
>>>>> base_type(reg->type) != PTR_TO_BTF_ID - the scalar rejection this
>>>>> test is
>>>>> named for - and which prints "invalid kptr access, R...". BPF_ST
>>>>> only gets
>>>>> the trivial "BPF_ST imm must be 0 when storing to kptr" immediate
>>>>> check and
>>>>> never reaches map_kptr_match_type() at all.
>>>>>
>>>>> So on a compiler that folds the constant - bpf-gcc, and clang from
>>>>> -mcpu=v4, which enabled BPF_ST around v4 support due to historical
>>>>> verifier limitations - the test fails against its expected message.
>>>>>
>>>>> Widening the __msg to accept either message would make it pass
>>>>> again, but
>>>>> on those toolchains it would then only re-test the imm != 0 path,
>>>>> which
>>>>> verifier/map_kptr.c ("map_kptr: BPF_ST imm != 0") already covers,
>>>>> and the
>>>>> scalar-vs-PTR_TO_BTF_ID check would lose its only test in the tree.
>>>>>
>>>>> Route the value through barrier_var() instead, so the store stays a
>>>>> BPF_STX everywhere and the test keeps asserting what it was
>>>>> written to
>>>>> assert. clang -mcpu=v1..v4 and bpf-gcc 16.1 all emit the register
>>>>> form
>>>>> afterwards.
>>>>>
>>>>> 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
>>>>>
>>>>> Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev>
>>>>> ---
>>>>> tools/testing/selftests/bpf/progs/map_kptr_fail.c | 11
>>>>> ++++++++++-
>>>>> 1 file changed, 10 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>>>>> b/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>>>>> index f11848dfa78f..cb84e23b83c0 100644
>>>>> --- a/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>>>>> +++ b/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>>>>> @@ -390,13 +390,22 @@ __failure __msg("invalid kptr access, R")
>>>>> int reject_scalar_store_to_kptr(struct __sk_buff *ctx)
>>>>> {
>>>>> struct map_value *v;
>>>>> + u64 val = 0xBADC0DE;
>>>>> int key = 0;
>>>>> v = bpf_map_lookup_elem(&array_map, &key);
>>>>> if (!v)
>>>>> return 0;
>>>>> - *(volatile u64 *)&v->unref_ptr = 0xBADC0DE;
>>>>> + /*
>>>>> + * Keep the value in a register so this stays a BPF_STX and
>>>>> keeps
>>>>> + * exercising map_kptr_match_type(). Compilers that fold the
>>>>> constant
>>>>> + * into a BPF_ST (store immediate) instead - bpf-gcc, and clang
>>>>> from
>>>>> + * -mcpu=v4 - would be rejected by the far weaker "BPF_ST imm
>>>>> must be
>>>>> + * 0" check, which verifier/map_kptr.c already covers.
>>>>> + */
>>>>> + barrier_var(val);
>>>>> + *(volatile u64 *)&v->unref_ptr = val;
>>>> Could you explain in details why gcc16 (with cpuv4) won't work with
>>>> BPF_ST?
>>>> What code gcc16 (with cpuv4) generates?
>>> GCC generates BPF_ST (and clang -mcpu=v4 does as well)
>>>
>>> 7: (7a) *(u64 *)(r0 +8) = 195936478
>>> BPF_ST imm must be 0 when storing to kptr at off=8
>>> processed 7 insns (limit 1000000) max_states_per_insn 0
>>> total_states
>>> 0 peak_states 0 mark_read 0
>>> =============
>>> EXPECTED SUBSTR: 'invalid kptr access, R'
>>>
>>>
>>> The issue is not codegen or BPF_ST vs. BPF_STX, its a deliberate bad
>>> write to a pointer.
>>> The current __msg in test only matches v3 (STX) form. v4's
>>> store-immediate hits a different verifier check with a different
>>> message.
>>> My first approach was to support both in the __msg, but then Claude
>>> suggested to not do it that way because it would reduce coverage as
>>> mentioned in the changelog above.
>> For clang side, we can do:
>>
>> diff --git a/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>> b/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>> index f11848dfa78f..b9f6d6764431 100644
>> --- a/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>> +++ b/tools/testing/selftests/bpf/progs/map_kptr_fail.c
>> @@ -386,7 +386,11 @@ int kptr_xchg_possibly_null(struct __sk_buff *ctx)
>> }
>> SEC("?tc")
>> +#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;
>> ...
>>
>> Note that __BPF_FEATURE_ST is only enabled for cpuv4 in clang.
>> Does gcc has similar macro like above __BPF_FEATURE_ST?
>
> Yes it does and also similarly enabled for cpu=v4.
> The suggestion does look cleaner, but feels fragile.
> Both forms of codegen are valid from selftest passing perspective.
> BPF_FEATURE_ST implies compiler supports the feature but the actual
> generation is subject to optimization level etc.
>
> Your call.
This is just for selftests. Let us have the above change to accommodate both cpuv2/cpuv3 and cpuv4.
>
> Thx,
> -Vineet
next prev parent reply other threads:[~2026-08-06 17:55 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-03 17:02 [bpf-next 0/4] selftest related fixes Vineet Gupta
2026-08-03 17:02 ` [bpf-next 1/4] selftests/bpf: map_kptr: force BPF_STX for the scalar store to kptr Vineet Gupta
2026-08-05 17:47 ` Yonghong Song
2026-08-05 19:25 ` Vineet Gupta
2026-08-06 16:37 ` Yonghong Song
2026-08-06 16:50 ` Vineet Gupta
2026-08-06 17:54 ` Yonghong Song [this message]
2026-08-03 17:02 ` [bpf-next 2/4] selftests/bpf: add --no-error-summary to skip end-of-run error log dump Vineet Gupta
2026-08-03 18:15 ` bot+bpf-ci
2026-08-03 19:48 ` Vineet Gupta
2026-08-03 17:02 ` [bpf-next 3/4] selftests/bpf: report failed subtest count in test_progs summary Vineet Gupta
2026-08-03 18:31 ` bot+bpf-ci
2026-08-03 18:36 ` Vineet Gupta
2026-08-03 17:02 ` [bpf-next 4/4] selftests/bpf: vmtest.sh: preserve command quoting when running in the VM Vineet Gupta
2026-08-03 18:31 ` bot+bpf-ci
2026-08-03 19:52 ` Vineet Gupta
2026-08-06 18:02 ` [bpf-next 0/4] selftest related fixes Yonghong Song
-- strict thread matches above, loose matches on Subject: below --
2026-08-03 16:51 Vineet Gupta
2026-08-03 16:51 ` [bpf-next 1/4] selftests/bpf: map_kptr: force BPF_STX for the scalar store to kptr Vineet Gupta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e6933505-662f-426b-a781-1243d8dba7f6@linux.dev \
--to=yonghong.song@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=vineet.gupta@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.