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: 6ccf49f793 ("bpf: Use SCEV to widen bounded loops")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261027190314.1440199-12-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-10-27 19:03:06 +00:00
parent 3c0ca9f9a9
commit 41750e5d68
No known key found for this signature in database

View File

@ -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: