From: Vineet Gupta <vineet.gupta@linux.dev>
To: bot+bpf-ci@kernel.org, ast@kernel.org, daniel@iogearbox.net,
andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com
Cc: martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev,
jolsa@kernel.org, emil@etsalapatis.com, ihor.solodrai@linux.dev,
john.fastabend@gmail.com, shuah@kernel.org, bpf@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
martin.lau@kernel.org, mason@kernel.org
Subject: Re: [PATCH bpf-next v3 05/12] selftests/bpf: Cover the low-32 link for zero-extending movs
Date: Mon, 26 Oct 2026 11:36:23 -0700 [thread overview]
Message-ID: <2a2d0450-01f5-4a87-9e4b-7ebecdbf165a@linux.dev> (raw)
In-Reply-To: <3e177386ed0ff37815ee705fb2cb8195952b4301858e4ff4e2b4638d14d94c3d@mail.kernel.org>
On 10/20/26 9:53 AM, bot+bpf-ci@kernel.org wrote:
>> selftests/bpf: Cover the low-32 link for zero-extending movs
> TL;DR:
> - Selftest comment calls the mixed-kind no-sync case unsound, but the program
> is safe; it is only lost precision
> - Commit message says "Twelve" programs, but there are thirteen
>
>> selftests/bpf: Cover the low-32 link for zero-extending movs
>>
>> Twelve programs, one per decision the previous patch makes:
>>
>> - zext_mov_narrow_src: narrowing the source reaches the destination
>> - zext_sync_makes_member_const: and over all 64 bits, since the member
>> is the zero-extension
>> - zext_narrow_dst_keeps_base: the reverse must not happen
>> - zext_u32_src_is_full_link: a provably-u32 source still propagates
>> - zext_self_mov_no_link: a self-mov mints no id
>> - zext_chain_drops_link: a second 32-bit mov drops the link
>> - zext_no_sync_between_mixed_kinds: differing kinds do not reach each
>> other, in either direction
>> - zext_no_sync_from_subreg_base: nor does a member reach a base whose
>> high half it knows nothing about
>> - zext_sync_between_two_subregs: two low-32 links on one base do
>> - zext_unlinked_path_stays_reachable: one unlinked path keeps the
>> guarded div reachable
>> - zext_mov_breaks_linked_src: forming the link drops the source's own
>> - zext_sync_keeps_narrower_member: narrowing the base does not widen a
>> member that already proved itself tighter
>> - zext_contradiction_keeps_range_sane: a contradiction leaves no empty
>> range behind, under BPF_F_TEST_REG_INVARIANTS so the violation is a
>> load failure rather than something only dmesg sees
>>
>> Written in asm so the bytecode is the same whichever compiler built the
>> suite.
>>
>> Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev>
> The changelog says "Twelve programs", but the list below it has thirteen
> bullets, and the patch adds thirteen programs:
>
> zext_mov_narrow_src, zext_sync_makes_member_const,
> zext_contradiction_keeps_range_sane, zext_narrow_dst_keeps_base,
> zext_u32_src_is_full_link, zext_self_mov_no_link, zext_chain_drops_link,
> zext_no_sync_between_mixed_kinds, zext_no_sync_from_subreg_base,
> zext_sync_between_two_subregs, zext_sync_keeps_narrower_member,
> zext_unlinked_path_stays_reachable and zext_mov_breaks_linked_src.
>
> The count looks like it was not updated when
> zext_contradiction_keeps_range_sane was added. It is the last bullet, but the
> third program in the file. Should "Twelve" be "Thirteen"?
Yes there was a last minute test update and this missed the update.
>> diff --git a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c
>> --- a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c
>> +++ b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c
> [ ... ]
>
>> @@ -710,4 +710,352 @@ l_exit_%=: \
> [ ... ]
>
>> +/*
>> + * Two members of one id set carrying different link kinds do not propagate
>> + * to each other: r7 is (u32)base and r8 is base + 3, and the deltas were
>> + * added at different ALU widths, so narrowing r8 says nothing about r7.
>> + * sync_linked_regs() declines the pair on the kinds before the deltas are
>> + * ever consulted. Note neither register is the base -- that is r6.
>> + */
>> +SEC("socket")
>> +__failure __msg("div by zero")
>> +__naked void zext_no_sync_between_mixed_kinds(void)
>> +{
>> + asm volatile (" \
>> + call %[bpf_get_prandom_u32]; \
>> + r6 = r0; \
>> + w7 = w6; /* forms the link */ \
>> + r8 = r6; \
>> + r8 += 3; /* r8 is BPF_REG_LINK_FULL, r7 is BPF_REG_LINK_ZEXT */ \
>> + if r8 != 3 goto 1f; /* must not propagate to r7 */ \
>> + if w7 == 0 goto 1f; \
>> + r0 /= 0; \
>> +1: \
>> + r0 = 0; \
>> + exit; \
>> +" :
>> + : __imm(bpf_get_prandom_u32)
>> + : __clobber_all);
>> +}
> ^^^^
>
> This isn't a bug, but is the comment accurate for this direction? It says
> narrowing r8 "says nothing about r7", and the asm comment says the narrowing
> "must not propagate to r7".
>
> r8 is a BPF_REG_LINK_FULL member, so r8 == r6 + 3 over all 64 bits. That
> relation inverts exactly, so knowing r8 pins the base, and r7 == (u32)(r8 - 3)
> follows.
>
> In this program the fall-through of "if r8 != 3 goto 1f" forces r6 == 0, so
> r7 == 0, "if w7 == 0 goto 1f" is always taken, and "r0 /= 0" cannot be reached
> at runtime. The program is safe. The verifier rejects it only because
> sync_linked_regs() skips every pair with differing kinds:
>
> if (reg->link_kind && known_reg->link_kind &&
> reg->link_kind != known_reg->link_kind)
> continue;
>
> That check exists for the other direction, a ZEXT known_reg against a FULL
> member (scalars_alu32_alu64_cross_type), where the 32-bit wrap really does
> break the relation. If the differencing arm ran for known=r8 (FULL, delta 3)
> and reg=r7 (ZEXT, delta 0), it would compute r8 + (0 - 3) and then
> zext_32_to_64(), which gives exactly (u32)(r8 - 3). That is sound.
>
> So this test pins a deliberate loss of precision, not a soundness requirement,
> but the comment presents it as unsound. The text is unchanged at the tip of
> the series. Someone who later makes the verifier propagate FULL -> ZEXT will
> see this test fail, and the comment will suggest the improvement is wrong.
>
> zext_chain_drops_link and zext_mov_breaks_linked_src also reject runtime-safe
> programs, but their comments say the link is dropped by rule. Could this one
> be worded the same way, for example "sync_linked_regs() declines mixed kinds
> even where, as here, the relation would hold"?
Yes this is correct as well, I'll update the comments.
Thx,
-Vineet
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/39458500836
next prev parent reply other threads:[~2026-10-26 18:36 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-20 16:18 [PATCH bpf-next v3 00/12] bpf: track scalar equality across the low 32 bits Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 01/12] bpf: Keep the 32-bit range across a sign extension that cannot change it Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 02/12] selftests/bpf: Cover sign extensions that cannot change the range Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 03/12] bpf: Prepare linked scalars for relations narrower than 64 bits Vineet Gupta
2026-10-20 17:08 ` bot+bpf-ci
2026-10-26 22:52 ` Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 04/12] bpf: Track low-32 scalar equality across zero-extending movs Vineet Gupta
2026-10-20 16:39 ` sashiko-bot
2026-10-26 23:06 ` Vineet Gupta
2026-10-20 17:09 ` bot+bpf-ci
2026-10-26 20:30 ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 05/12] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:53 ` bot+bpf-ci
2026-10-26 18:36 ` Vineet Gupta [this message]
2026-10-20 16:19 ` [PATCH bpf-next v3 06/12] bpf: Track low-32 scalar equality across sign-extending movs Vineet Gupta
2026-10-20 16:57 ` sashiko-bot
2026-10-26 20:46 ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 07/12] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 08/12] bpf: Recover the low 32 bits on the reverse link direction Vineet Gupta
2026-10-20 16:53 ` bot+bpf-ci
2026-10-26 19:57 ` Vineet Gupta
2026-10-20 17:20 ` sashiko-bot
2026-10-26 21:28 ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 09/12] bpf: Track low-32 scalar equality across narrowing stack fills Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 10/12] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:29 ` sashiko-bot
2026-10-20 17:15 ` Vineet Gupta
2026-10-20 16:52 ` bot+bpf-ci
2026-10-26 20:21 ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 11/12] [do not merge] bpf: Track low-32 scalar equality across narrowing stack spills Vineet Gupta
2026-10-20 16:42 ` sashiko-bot
2026-10-26 21:51 ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 12/12] [do not merge] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:32 ` sashiko-bot
2026-10-26 22:01 ` 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=2a2d0450-01f5-4a87-9e4b-7ebecdbf165a@linux.dev \
--to=vineet.gupta@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bot+bpf-ci@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@kernel.org \
--cc=martin.lau@linux.dev \
--cc=mason@kernel.org \
--cc=memxor@gmail.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=yonghong.song@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.