Commit 9d35d6d
bpf: Fix tnum_overlap to check for zero mask first
Syzbot reported a kernel warning due to a range invariant violation in
the BPF verifier. The issue occurs when tnum_overlap() fails to detect
that two tnums don't have any overlapping bits.
The problematic BPF program:
0: call bpf_get_prandom_u32
1: r6 = r0
2: r6 &= 0xFFFFFFFFFFFFFFF0
3: r7 = r0
4: r7 &= 0x07
5: r7 -= 0xFF
6: if r6 == r7 goto <exit>
After instruction 5, R7 has the range:
R7: u64=[0xffffffffffffff01, 0xffffffffffffff08] var_off=(0xffffffffffffff00; 0xf)
R6 and R7 don't overlap since they have no agreeing bits. However,
is_branch_taken() fails to recognize this, causing the verifier to
refine register bounds and end up with inconsistent bounds:
6: if r6 == r7 goto <exit>
R6: u64=[0xffffffffffffff01, 0xffffffffffffff00] var_off=(0xffffffffffffff00, 0x0)
R7: u64=[0xffffffffffffff01, 0xffffffffffffff00] var_off=(0xffffffffffffff00, 0x0)
The root cause is that tnum_overlap() doesn't properly handle the case
where the masks have no overlapping bits.
Fix this by adding an early check for zero mask intersection in tnum_overlap().
Reported-by: [email protected]
Fixes: f41345f ("bpf: Use tnums for JEQ/JNE is_branch_taken logic")
Signed-off-by: KaFai Wan <[email protected]>1 parent e5828a2 commit 9d35d6d
1 file changed
+2
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
163 | 163 | | |
164 | 164 | | |
165 | 165 | | |
| 166 | + | |
| 167 | + | |
166 | 168 | | |
167 | 169 | | |
168 | 170 | | |
| |||
0 commit comments