From: Daniel Borkmann Date: Tue, 7 Apr 2026 19:24:21 +0000 (+0200) Subject: selftests/bpf: Add tests for stale delta leaking through id reassignment X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=cac16ce1e3786bd98cec0c108e3bc06ed3d3c6a9;p=thirdparty%2Fkernel%2Flinux.git selftests/bpf: Add tests for stale delta leaking through id reassignment Extend the verifier_linked_scalars BPF selftest with a stale delta test such that the div-by-zero path is rejected in the fixed case. # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_linked_scalars [...] ./test_progs -t verifier_linked_scalars #612/1 verifier_linked_scalars/scalars: find linked scalars:OK #612/2 verifier_linked_scalars/sync_linked_regs_preserves_id:OK #612/3 verifier_linked_scalars/scalars_neg:OK #612/4 verifier_linked_scalars/scalars_neg_sub:OK #612/5 verifier_linked_scalars/scalars_neg_alu32_add:OK #612/6 verifier_linked_scalars/scalars_neg_alu32_sub:OK #612/7 verifier_linked_scalars/scalars_pos:OK #612/8 verifier_linked_scalars/scalars_sub_neg_imm:OK #612/9 verifier_linked_scalars/scalars_double_add:OK #612/10 verifier_linked_scalars/scalars_sync_delta_overflow:OK #612/11 verifier_linked_scalars/scalars_sync_delta_overflow_large_range:OK #612/12 verifier_linked_scalars/scalars_alu32_big_offset:OK #612/13 verifier_linked_scalars/scalars_alu32_basic:OK #612/14 verifier_linked_scalars/scalars_alu32_wrap:OK #612/15 verifier_linked_scalars/scalars_alu32_zext_linked_reg:OK #612/16 verifier_linked_scalars/scalars_alu32_alu64_cross_type:OK #612/17 verifier_linked_scalars/scalars_alu32_alu64_regsafe_pruning:OK #612/18 verifier_linked_scalars/alu32_negative_offset:OK #612/19 verifier_linked_scalars/spurious_precision_marks:OK #612/20 verifier_linked_scalars/scalars_self_add_clears_id:OK #612/21 verifier_linked_scalars/scalars_self_add_alu32_clears_id:OK #612/22 verifier_linked_scalars/scalars_stale_delta_from_cleared_id:OK #612/23 verifier_linked_scalars/scalars_stale_delta_from_cleared_id_alu32:OK #612 verifier_linked_scalars:OK Summary: 1/23 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/r/20260407192421.508817-4-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov --- diff --git a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c index 09146e5db0610..60a6f246e2d17 100644 --- a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c +++ b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c @@ -592,4 +592,59 @@ l_exit_%=: \ : __clobber_all); } +/* + * Test that stale delta from a cleared BPF_ADD_CONST does not leak + * through assign_scalar_id_before_mov() into a new id, causing + * sync_linked_regs() to compute an incorrect offset. + */ +SEC("socket") +__failure +__msg("div by zero") +__naked void scalars_stale_delta_from_cleared_id(void) +{ + asm volatile (" \ + call %[bpf_get_prandom_u32]; \ + r6 = r0; /* r6 unknown, gets id A */ \ + r6 += 5; /* id A|ADD_CONST, delta 5 */ \ + r6 ^= 0; /* id cleared; delta stays 5 */ \ + r8 = r6; /* new id B, stale delta 5 */ \ + r8 += 3; /* id B|ADD_CONST, delta 3 */ \ + r9 = r6; /* id B, stale delta 5 */ \ + if r9 != 10 goto l_exit_%=; \ + /* Bug: r8 = 10+(3-5) = 8; Fix: r8 = 10+(3-0) = 13 */ \ + if r8 == 8 goto l_exit_%=; \ + r0 /= 0; \ +l_exit_%=: \ + r0 = 0; \ + exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +/* Same as above but with alu32. */ +SEC("socket") +__failure +__msg("div by zero") +__naked void scalars_stale_delta_from_cleared_id_alu32(void) +{ + asm volatile (" \ + call %[bpf_get_prandom_u32]; \ + w6 = w0; \ + w6 += 5; \ + w6 ^= 0; \ + w8 = w6; \ + w8 += 3; \ + w9 = w6; \ + if w9 != 10 goto l_exit_%=; \ + if w8 == 8 goto l_exit_%=; \ + r0 /= 0; \ +l_exit_%=: \ + r0 = 0; \ + exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + char _license[] SEC("license") = "GPL";