- 
        Couldn't load subscription status. 
- Fork 145
bpf: Fix tnum_overlap to check for zero mask first #10103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| Upstream branch: e758657 | 
ecdeefe    to
    10ce4bd      
    Compare
  
    | Upstream branch: ff88079 | 
b7b7c66    to
    34839bb      
    Compare
  
    10ce4bd    to
    e5828a2      
    Compare
  
    | Upstream branch: f9db3a3 | 
34839bb    to
    3ce5d4c      
    Compare
  
    e5828a2    to
    13927c8      
    Compare
  
    | Upstream branch: 8842732 | 
3ce5d4c    to
    a4d4eed      
    Compare
  
    13927c8    to
    9b73883      
    Compare
  
    | Upstream branch: 23f852d | 
a4d4eed    to
    76a70df      
    Compare
  
    9b73883    to
    3cfe497      
    Compare
  
    | Upstream branch: 54c134f | 
76a70df    to
    7da51eb      
    Compare
  
    3cfe497    to
    6d6792d      
    Compare
  
    | Upstream branch: 9f317bd | 
7da51eb    to
    50176c7      
    Compare
  
    6d6792d    to
    4481a85      
    Compare
  
    | Upstream branch: 54c134f | 
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]>
50176c7    to
    51ba0cb      
    Compare
  
    | At least one diff in series https://patchwork.kernel.org/project/netdevbpf/list/?series=1015928 expired. Closing PR. | 
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