]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests: bpf: Add test for multiple syncs from linked register
authorPuranjay Mohan <puranjay@kernel.org>
Thu, 15 Jan 2026 15:11:41 +0000 (07:11 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 16 Jan 2026 18:08:59 +0000 (10:08 -0800)
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>
tools/testing/selftests/bpf/progs/verifier_linked_scalars.c

index 8f755d2464cf5edd77cfea33beceeaead654389d..5f41bbb730a7136657b13352714ddd2c3f74819a 100644 (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";