Skip to content

Conversation

@kernel-patches-daemon-bpf
Copy link

Pull request for series with
subject: bpf: Fix tnum_overlap to check for zero mask first
version: 1
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1015928

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: e758657
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1015928
version: 1

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: ff88079
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1015928
version: 1

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]>
This patch adds coverage for the warning detected by syzkaller and fixed
in the previous patch. Without the previous patch, this test fails with:

  verifier bug: REG INVARIANTS VIOLATION (true_reg1): range bounds
  violation u64=[0xffffffffffffff01, 0xffffffffffffff00]
  s64=[0xffffffffffffff01, 0xffffffffffffff00]
  u32=[0xffffff01, 0xffffff00] s32=[0xffffff00, 0xffffff00]
  var_off=(0xffffffffffffff00, 0x0)
  verifier bug: REG INVARIANTS VIOLATION (true_reg2): range bounds
  violation u64=[0xffffffffffffff01, 0xffffffffffffff00]
  s64=[0xffffffffffffff01, 0xffffffffffffff00]
  u32=[0xffffff01, 0xffffff00] s32=[0xffffff01, 0xffffff00]
  var_off=(0xffffffffffffff00, 0x0)

Signed-off-by: KaFai Wan <[email protected]>
@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: f9db3a3
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1015928
version: 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant