From 41750e5d682ab0703a9d2af3ec31a508b253b38f Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 27 Oct 2026 19:03:06 +0000 Subject: bpf: Don't widen a pointer to a buffer in scalar evolution Scalar evolution widens counted loops. Since that change the verifier rejects a loop over the per-cpu values of a map element: SEC("iter/bpf_map_elem") ... for (i = 0; i < n; i++) { out[i] = *(__u32 *)pptr; pptr += 8; } loop header at 12, widening r2 to 0..56 step 8 R2 invalid variable buffer offset: off=0, var_off=(0x0; 0x38) pptr is a pointer to a buffer (PTR_TO_BUF). Scalar evolution replaces its offset with the range over all iterations. But __check_buffer_access() accepts only a constant offset. Thus a prog cannot use a widened PTR_TO_BUF. Do not widen it. Then the verifier verifies the loop one iteration at a time, as it did before. loop before SCEV with SCEV this patch -------------------------------- ----------- ---------- ---------- counts in i, reads through pptr loads rejected loads counts in p ('p < end'), no read 1M insns loads 1M insns counts in p, reads through p 1M insns rejected 1M insns The verifier cannot decide a comparison of two pointers to a buffer. Thus it follows 'p < end' until the limit of 1M insns. bpf_iter_bpf_percpu_array_map.c and bpf_iter_bpf_percpu_hash_map.c have the first loop. They load today because num_cpus is volatile. The prog reads the bound again in each iteration. Scalar evolution cannot count such a loop, and it widens nothing. Fixes: 6ccf49f79327 ("bpf: Use SCEV to widen bounded loops") Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20261027190314.1440199-12-alexei.starovoitov@gmail.com --- kernel/bpf/scev.c | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel') diff --git a/kernel/bpf/scev.c b/kernel/bpf/scev.c index 3f7534cda47a..6231d16aa311 100644 --- a/kernel/bpf/scev.c +++ b/kernel/bpf/scev.c @@ -2379,7 +2379,6 @@ static bool is_widenable_reg_type(const struct bpf_reg_state *reg) case PTR_TO_PACKET: case PTR_TO_PACKET_META: case PTR_TO_MEM: - case PTR_TO_BUF: case PTR_TO_BTF_ID: return true; default: -- cgit v1.2.3