BPF verifier gains 32-bit loop analysis, ships with pointer bug
Eduard Zingerman’s scalar-evolution work cuts verification cost sharply, but 32-bit pointer latches can undercount iterations and mis-bound memory access.
The BPF verifier can now track linear scalar evolution through 32-bit ALU loops and 32-bit conditional jumps, a change that landed in bpf-next after work by Eduard Zingerman. The goal is tighter, more accurate loop bounds for common patterns that only update and test the low half of a register, rather than forcing the verifier to treat those loops as opaque.
On large program sets drawn from Cilium, Meta, sched_ext, and selftests, verification success stayed flat while instruction counts fell hard for many loops. Several programs dropped from tens or hundreds of thousands of verified instructions to a few dozen, with top cases near 99 percent reductions and no regressions among the ranked wins.
Review still flagged a real safety hole before the series fully settled. For privileged programs, 32-bit jumps that compare two pointers can now feed the new iteration math. That path can treat pointer offsets like ordinary scalars and produce a maximum header count that is too small. Widening and clamping then pin the induction pointer to a range that is not a true upper bound. Alexei Starovoitov illustrated the failure with a map-value walk that steps by eight bytes under a 32-bit comparison: if the low 32 bits of the bound wrap, the latch stays true and the pointer can walk past the map object while the verifier still believes the range is safe.
Starovoitov called the issue real and asked for a follow-up. Zingerman agreed to reject 32-bit pointer latches in a fix the same day, and said clamping edge cases that can empty a 32-bit range or mishandle pointers still need more thought. Separate review also noted a selftest log expectation that would have broken bisect until moved into the main change.
The series was applied to bpf-next with the understanding that the pointer case would be closed promptly. Until then, the new 32-bit evolution path improves precision for ordinary scalar loops while leaving a known hole around privileged 32-bit pointer comparisons.