WARNING in reg_bounds_sanity_check - const subreg tnum out of sync after ALU64 add
Hiker Cl <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel,org.kernel.vger.bpf |
|---|---|
| Message-ID | <CAGM=xGB1fJ9kT8XTitVo74B0WGqgjkoUHdLwzytwV0AyqeVApw@mail.gmail.com> |
Hi BPF maintainers,
I'm reporting a kernel WARNING (verifier internal-invariant violation) I
encountered on the BPF subsystem, reproducible on Linux 7.2.0-rc6
(bpf-next f5b57e9e9) and 7.2.0-rc7 (mainline 15ef2f78c).
### Summary
A 19-instruction SOCKET_FILTER program, loaded by an unprivileged user
(unprivileged_bpf_disabled=0, no CAP_BPF), triggers:
verifier bug: REG INVARIANTS VIOLATION (alu): const subreg tnum out of
sync with range bounds
r64={.base=0x0, .size=0x0} r32={.base=0x0, .size=0xffffffff}
var_off=(0x0, 0x0)
The 64-bit register and var_off are both precise (const 0), but the 32-bit
subregister range is fully unknown -- an internal inconsistency in
subregister precision tracking. reg_bounds_sanity_check() fires from the
check_alu_op() path after `r0 += r1` (64-bit add of a map_value pointer and
a ktime-derived bounded scalar). The WARNING only fires on the unprivileged
verification path; the privileged path verifies the same program cleanly.
### Steps to Reproduce (raw instruction sequence)
One ARRAY map (key_size=4, value_size=48, max_entries=1); its fd patched
into insn 6-7 as BPF_PSEUDO_MAP_FD:
0 r0 = bpf_ktime_get_ns() /* call 5 */
1 *(u64 *)(r10 - 16) = r0
2 r1 = 0
3 *(u64 *)(r10 - 8) = r1
4 r2 = r10
5 r2 += -8
6-7 r1 = map fd /* LD_IMM64 */
8 r0 = bpf_map_lookup_elem(r1, r2) /* call 1 */
9 if r0 == 0 goto +7
10 r1 = *(u64 *)(r10 - 16) /* reload ktime */
11 r2 = 0x40000000
12 if r1 > r2 goto +4
13 if r1 s> 1 goto +3
/* r1 in [1, 0x40000000] */
14 r0 += r1 /* (*) WARNING fires here */
15 r9 = r0
16 *(u8 *)r0 = r1
17 r0 = 0
18 exit
Full bug report (with kernel log) is filed on Bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=221899
### Notes
This message ("const subreg tnum out of sync with range bounds",
const_tnum_range_mismatch_32, check_alu_op) is distinct from the syzbot
report "WARNING in reg_bounds_sanity_check (2)"
(https://syzbot.org/bug?id=8e3413235092cdd148efd146f97ea9960cdd23ca),
whose message is "range bounds violation" and which fires from the
conditional-jump path (reg_set_min_max). Both the 2025-09 fix and the
2026-03 "Simulate branches" series are present in the kernels tested, yet
this path still triggers.
Please let me know if you need more information or if I can help test a
patch