selftests: bpf: Add test for multiple syncs from linked register

Before the last commit, sync_linked_regs() corrupted the register whose
bounds are being updated by copying known_reg's id to it. The ids are
the same in value but known_reg has the BPF_ADD_CONST flag which is
wrongly copied to reg.

This later causes issues when creating new links to this reg.
assign_scalar_id_before_mov() sees this BPF_ADD_CONST and gives a new id
to this register and breaks the old links. This is exposed by the added
selftest.

Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Tested-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260115151143.1344724-3-puranjay@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Puranjay Mohan 2026-01-15 07:11:41 -08:00 committed by Alexei Starovoitov
parent af9e89d8dd
commit 086c99fbe4

View File

@ -31,4 +31,37 @@ l1: \
" ::: __clobber_all);
}
/*
* Test that sync_linked_regs() preserves register IDs.
*
* The sync_linked_regs() function copies bounds from known_reg to linked
* registers. When doing so, it must preserve each register's original id
* to allow subsequent syncs from the same source to work correctly.
*
*/
SEC("socket")
__success
__naked void sync_linked_regs_preserves_id(void)
{
asm volatile (" \
call %[bpf_get_prandom_u32]; \
r0 &= 0xff; /* r0 in [0, 255] */ \
r1 = r0; /* r0, r1 linked with id 1 */ \
r1 += 4; /* r1 has id=1 and off=4 in [4, 259] */ \
if r1 < 10 goto l0_%=; \
/* r1 in [10, 259], r0 synced to [6, 255] */ \
r2 = r0; /* r2 has id=1 and in [6, 255] */ \
if r1 < 14 goto l0_%=; \
/* r1 in [14, 259], r0 synced to [10, 255] */ \
if r0 >= 10 goto l0_%=; \
/* Never executed */ \
r0 /= 0; \
l0_%=: \
r0 = 0; \
exit; \
" :
: __imm(bpf_get_prandom_u32)
: __clobber_all);
}
char _license[] SEC("license") = "GPL";