Two test cases for signed/unsigned 32-bit bounds refinement when s32 range crosses the sign boundary: - s32 range [S32_MIN..1] overlapping with u32 range [3..U32_MAX], s32 range tail before sign boundary overlaps with u32 range. - s32 range [-3..5] overlapping with u32 range [0..S32_MIN+3], s32 range head after the sign boundary overlaps with u32 range. This covers both branches added in the __reg32_deduce_bounds(). Also, crossing_32_bit_signed_boundary_2() no longer triggers invariant violations.
Unified · Split
| @@ -1148,7 +1148,7 @@ l0_%=: r0 = 0; \ · 1147 unmodified lines | ||
| 1148 | 1148 | SEC("xdp") |
| 1149 | 1149 | __description("bound check with JMP32_JSLT for crossing 32-bit signed boundary") |
| 1150 | 1150 | __success __retval(0) |
| 1151 | −__flag(!BPF_F_TEST_REG_INVARIANTS) /* known invariants violation */ | |
| 1151 | +__flag(BPF_F_TEST_REG_INVARIANTS) | |
| 1152 | 1152 | __naked void crossing_32_bit_signed_boundary_2(void) |
| 1153 | 1153 | { |
| 1154 | 1154 | asm volatile (" \ |
| @@ -2000,4 +2000,41 @@ __naked void bounds_refinement_multiple_overlaps(void *ctx) · 845 unmodified lines | ||
| 2000 | 2000 | : __clobber_all); |
| 2001 | 2001 | } |
| 2002 | 2002 | |
| 2003 | +SEC("socket") | |
| 2004 | +__success | |
| 2005 | +__flag(BPF_F_TEST_REG_INVARIANTS) | |
| 2006 | +__naked void signed_unsigned_intersection32_case1(void *ctx) | |
| 2007 | +{ | |
| 2008 | + asm volatile(" \ | |
| 2009 | + call %[bpf_get_prandom_u32]; \ | |
| 2010 | + w0 &= 0xffffffff; \ | |
| 2011 | + if w0 < 0x3 goto 1f; /* on fall-through u32 range [3..U32_MAX] */ \ | |
| 2012 | + if w0 s> 0x1 goto 1f; /* on fall-through s32 range [S32_MIN..1] */ \ | |
| 2013 | + if w0 s< 0x0 goto 1f; /* range can be narrowed to [S32_MIN..-1] */ \ | |
| 2014 | + r10 = 0; /* thus predicting the jump. */ \ | |
| 2015 | +1: exit; \ | |
| 2016 | +" : | |
| 2017 | + : __imm(bpf_get_prandom_u32) | |
| 2018 | + : __clobber_all); | |
| 2019 | +} | |
| 2020 | + | |
| 2021 | +SEC("socket") | |
| 2022 | +__success | |
| 2023 | +__flag(BPF_F_TEST_REG_INVARIANTS) | |
| 2024 | +__naked void signed_unsigned_intersection32_case2(void *ctx) | |
| 2025 | +{ | |
| 2026 | + asm volatile(" \ | |
| 2027 | + call %[bpf_get_prandom_u32]; \ | |
| 2028 | + w0 &= 0xffffffff; \ | |
| 2029 | + if w0 > 0x80000003 goto 1f; /* on fall-through u32 range [0..S32_MIN+3] */ \ | |
| 2030 | + if w0 s< -3 goto 1f; /* on fall-through s32 range [-3..S32_MAX] */ \ | |
| 2031 | + if w0 s> 5 goto 1f; /* on fall-through s32 range [-3..5] */ \ | |
| 2032 | + if w0 <= 5 goto 1f; /* range can be narrowed to [0..5] */ \ | |
| 2033 | + r10 = 0; /* thus predicting the jump */ \ | |
| 2034 | +1: exit; \ | |
| 2035 | +" : | |
| 2036 | + : __imm(bpf_get_prandom_u32) | |
| 2037 | + : __clobber_all); | |
| 2038 | +} | |
| 2039 | + | |
| 2003 | 2040 | char _license[] SEC("license") = "GPL"; |