162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Converted from tools/testing/selftests/bpf/verifier/bounds.c */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/bpf.h> 562306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 662306a36Sopenharmony_ci#include "bpf_misc.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_cistruct { 962306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 1062306a36Sopenharmony_ci __uint(max_entries, 1); 1162306a36Sopenharmony_ci __type(key, long long); 1262306a36Sopenharmony_ci __type(value, long long); 1362306a36Sopenharmony_ci} map_hash_8b SEC(".maps"); 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciSEC("socket") 1662306a36Sopenharmony_ci__description("subtraction bounds (map value) variant 1") 1762306a36Sopenharmony_ci__failure __msg("R0 max value is outside of the allowed memory range") 1862306a36Sopenharmony_ci__failure_unpriv 1962306a36Sopenharmony_ci__naked void bounds_map_value_variant_1(void) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci asm volatile (" \ 2262306a36Sopenharmony_ci r1 = 0; \ 2362306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 2462306a36Sopenharmony_ci r2 = r10; \ 2562306a36Sopenharmony_ci r2 += -8; \ 2662306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 2762306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 2862306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 2962306a36Sopenharmony_ci r1 = *(u8*)(r0 + 0); \ 3062306a36Sopenharmony_ci if r1 > 0xff goto l0_%=; \ 3162306a36Sopenharmony_ci r3 = *(u8*)(r0 + 1); \ 3262306a36Sopenharmony_ci if r3 > 0xff goto l0_%=; \ 3362306a36Sopenharmony_ci r1 -= r3; \ 3462306a36Sopenharmony_ci r1 >>= 56; \ 3562306a36Sopenharmony_ci r0 += r1; \ 3662306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 3762306a36Sopenharmony_ci exit; \ 3862306a36Sopenharmony_cil0_%=: r0 = 0; \ 3962306a36Sopenharmony_ci exit; \ 4062306a36Sopenharmony_ci" : 4162306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 4262306a36Sopenharmony_ci __imm_addr(map_hash_8b) 4362306a36Sopenharmony_ci : __clobber_all); 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciSEC("socket") 4762306a36Sopenharmony_ci__description("subtraction bounds (map value) variant 2") 4862306a36Sopenharmony_ci__failure 4962306a36Sopenharmony_ci__msg("R0 min value is negative, either use unsigned index or do a if (index >=0) check.") 5062306a36Sopenharmony_ci__msg_unpriv("R1 has unknown scalar with mixed signed bounds") 5162306a36Sopenharmony_ci__naked void bounds_map_value_variant_2(void) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci asm volatile (" \ 5462306a36Sopenharmony_ci r1 = 0; \ 5562306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 5662306a36Sopenharmony_ci r2 = r10; \ 5762306a36Sopenharmony_ci r2 += -8; \ 5862306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 5962306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 6062306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 6162306a36Sopenharmony_ci r1 = *(u8*)(r0 + 0); \ 6262306a36Sopenharmony_ci if r1 > 0xff goto l0_%=; \ 6362306a36Sopenharmony_ci r3 = *(u8*)(r0 + 1); \ 6462306a36Sopenharmony_ci if r3 > 0xff goto l0_%=; \ 6562306a36Sopenharmony_ci r1 -= r3; \ 6662306a36Sopenharmony_ci r0 += r1; \ 6762306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 6862306a36Sopenharmony_ci exit; \ 6962306a36Sopenharmony_cil0_%=: r0 = 0; \ 7062306a36Sopenharmony_ci exit; \ 7162306a36Sopenharmony_ci" : 7262306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 7362306a36Sopenharmony_ci __imm_addr(map_hash_8b) 7462306a36Sopenharmony_ci : __clobber_all); 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ciSEC("socket") 7862306a36Sopenharmony_ci__description("check subtraction on pointers for unpriv") 7962306a36Sopenharmony_ci__success __failure_unpriv __msg_unpriv("R9 pointer -= pointer prohibited") 8062306a36Sopenharmony_ci__retval(0) 8162306a36Sopenharmony_ci__naked void subtraction_on_pointers_for_unpriv(void) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci asm volatile (" \ 8462306a36Sopenharmony_ci r0 = 0; \ 8562306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 8662306a36Sopenharmony_ci r2 = r10; \ 8762306a36Sopenharmony_ci r2 += -8; \ 8862306a36Sopenharmony_ci r6 = 9; \ 8962306a36Sopenharmony_ci *(u64*)(r2 + 0) = r6; \ 9062306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 9162306a36Sopenharmony_ci r9 = r10; \ 9262306a36Sopenharmony_ci r9 -= r0; \ 9362306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 9462306a36Sopenharmony_ci r2 = r10; \ 9562306a36Sopenharmony_ci r2 += -8; \ 9662306a36Sopenharmony_ci r6 = 0; \ 9762306a36Sopenharmony_ci *(u64*)(r2 + 0) = r6; \ 9862306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 9962306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 10062306a36Sopenharmony_ci exit; \ 10162306a36Sopenharmony_cil0_%=: *(u64*)(r0 + 0) = r9; \ 10262306a36Sopenharmony_ci r0 = 0; \ 10362306a36Sopenharmony_ci exit; \ 10462306a36Sopenharmony_ci" : 10562306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 10662306a36Sopenharmony_ci __imm_addr(map_hash_8b) 10762306a36Sopenharmony_ci : __clobber_all); 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ciSEC("socket") 11162306a36Sopenharmony_ci__description("bounds check based on zero-extended MOV") 11262306a36Sopenharmony_ci__success __success_unpriv __retval(0) 11362306a36Sopenharmony_ci__naked void based_on_zero_extended_mov(void) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci asm volatile (" \ 11662306a36Sopenharmony_ci r1 = 0; \ 11762306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 11862306a36Sopenharmony_ci r2 = r10; \ 11962306a36Sopenharmony_ci r2 += -8; \ 12062306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 12162306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 12262306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 12362306a36Sopenharmony_ci /* r2 = 0x0000'0000'ffff'ffff */ \ 12462306a36Sopenharmony_ci w2 = 0xffffffff; \ 12562306a36Sopenharmony_ci /* r2 = 0 */ \ 12662306a36Sopenharmony_ci r2 >>= 32; \ 12762306a36Sopenharmony_ci /* no-op */ \ 12862306a36Sopenharmony_ci r0 += r2; \ 12962306a36Sopenharmony_ci /* access at offset 0 */ \ 13062306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 13162306a36Sopenharmony_cil0_%=: /* exit */ \ 13262306a36Sopenharmony_ci r0 = 0; \ 13362306a36Sopenharmony_ci exit; \ 13462306a36Sopenharmony_ci" : 13562306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 13662306a36Sopenharmony_ci __imm_addr(map_hash_8b) 13762306a36Sopenharmony_ci : __clobber_all); 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ciSEC("socket") 14162306a36Sopenharmony_ci__description("bounds check based on sign-extended MOV. test1") 14262306a36Sopenharmony_ci__failure __msg("map_value pointer and 4294967295") 14362306a36Sopenharmony_ci__failure_unpriv 14462306a36Sopenharmony_ci__naked void on_sign_extended_mov_test1(void) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci asm volatile (" \ 14762306a36Sopenharmony_ci r1 = 0; \ 14862306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 14962306a36Sopenharmony_ci r2 = r10; \ 15062306a36Sopenharmony_ci r2 += -8; \ 15162306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 15262306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 15362306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 15462306a36Sopenharmony_ci /* r2 = 0xffff'ffff'ffff'ffff */ \ 15562306a36Sopenharmony_ci r2 = 0xffffffff; \ 15662306a36Sopenharmony_ci /* r2 = 0xffff'ffff */ \ 15762306a36Sopenharmony_ci r2 >>= 32; \ 15862306a36Sopenharmony_ci /* r0 = <oob pointer> */ \ 15962306a36Sopenharmony_ci r0 += r2; \ 16062306a36Sopenharmony_ci /* access to OOB pointer */ \ 16162306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 16262306a36Sopenharmony_cil0_%=: /* exit */ \ 16362306a36Sopenharmony_ci r0 = 0; \ 16462306a36Sopenharmony_ci exit; \ 16562306a36Sopenharmony_ci" : 16662306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 16762306a36Sopenharmony_ci __imm_addr(map_hash_8b) 16862306a36Sopenharmony_ci : __clobber_all); 16962306a36Sopenharmony_ci} 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ciSEC("socket") 17262306a36Sopenharmony_ci__description("bounds check based on sign-extended MOV. test2") 17362306a36Sopenharmony_ci__failure __msg("R0 min value is outside of the allowed memory range") 17462306a36Sopenharmony_ci__failure_unpriv 17562306a36Sopenharmony_ci__naked void on_sign_extended_mov_test2(void) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci asm volatile (" \ 17862306a36Sopenharmony_ci r1 = 0; \ 17962306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 18062306a36Sopenharmony_ci r2 = r10; \ 18162306a36Sopenharmony_ci r2 += -8; \ 18262306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 18362306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 18462306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 18562306a36Sopenharmony_ci /* r2 = 0xffff'ffff'ffff'ffff */ \ 18662306a36Sopenharmony_ci r2 = 0xffffffff; \ 18762306a36Sopenharmony_ci /* r2 = 0xfff'ffff */ \ 18862306a36Sopenharmony_ci r2 >>= 36; \ 18962306a36Sopenharmony_ci /* r0 = <oob pointer> */ \ 19062306a36Sopenharmony_ci r0 += r2; \ 19162306a36Sopenharmony_ci /* access to OOB pointer */ \ 19262306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 19362306a36Sopenharmony_cil0_%=: /* exit */ \ 19462306a36Sopenharmony_ci r0 = 0; \ 19562306a36Sopenharmony_ci exit; \ 19662306a36Sopenharmony_ci" : 19762306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 19862306a36Sopenharmony_ci __imm_addr(map_hash_8b) 19962306a36Sopenharmony_ci : __clobber_all); 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ciSEC("tc") 20362306a36Sopenharmony_ci__description("bounds check based on reg_off + var_off + insn_off. test1") 20462306a36Sopenharmony_ci__failure __msg("value_size=8 off=1073741825") 20562306a36Sopenharmony_ci__naked void var_off_insn_off_test1(void) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci asm volatile (" \ 20862306a36Sopenharmony_ci r6 = *(u32*)(r1 + %[__sk_buff_mark]); \ 20962306a36Sopenharmony_ci r1 = 0; \ 21062306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 21162306a36Sopenharmony_ci r2 = r10; \ 21262306a36Sopenharmony_ci r2 += -8; \ 21362306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 21462306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 21562306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 21662306a36Sopenharmony_ci r6 &= 1; \ 21762306a36Sopenharmony_ci r6 += %[__imm_0]; \ 21862306a36Sopenharmony_ci r0 += r6; \ 21962306a36Sopenharmony_ci r0 += %[__imm_0]; \ 22062306a36Sopenharmony_cil0_%=: r0 = *(u8*)(r0 + 3); \ 22162306a36Sopenharmony_ci r0 = 0; \ 22262306a36Sopenharmony_ci exit; \ 22362306a36Sopenharmony_ci" : 22462306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 22562306a36Sopenharmony_ci __imm_addr(map_hash_8b), 22662306a36Sopenharmony_ci __imm_const(__imm_0, (1 << 29) - 1), 22762306a36Sopenharmony_ci __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) 22862306a36Sopenharmony_ci : __clobber_all); 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ciSEC("tc") 23262306a36Sopenharmony_ci__description("bounds check based on reg_off + var_off + insn_off. test2") 23362306a36Sopenharmony_ci__failure __msg("value 1073741823") 23462306a36Sopenharmony_ci__naked void var_off_insn_off_test2(void) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci asm volatile (" \ 23762306a36Sopenharmony_ci r6 = *(u32*)(r1 + %[__sk_buff_mark]); \ 23862306a36Sopenharmony_ci r1 = 0; \ 23962306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 24062306a36Sopenharmony_ci r2 = r10; \ 24162306a36Sopenharmony_ci r2 += -8; \ 24262306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 24362306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 24462306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 24562306a36Sopenharmony_ci r6 &= 1; \ 24662306a36Sopenharmony_ci r6 += %[__imm_0]; \ 24762306a36Sopenharmony_ci r0 += r6; \ 24862306a36Sopenharmony_ci r0 += %[__imm_1]; \ 24962306a36Sopenharmony_cil0_%=: r0 = *(u8*)(r0 + 3); \ 25062306a36Sopenharmony_ci r0 = 0; \ 25162306a36Sopenharmony_ci exit; \ 25262306a36Sopenharmony_ci" : 25362306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 25462306a36Sopenharmony_ci __imm_addr(map_hash_8b), 25562306a36Sopenharmony_ci __imm_const(__imm_0, (1 << 30) - 1), 25662306a36Sopenharmony_ci __imm_const(__imm_1, (1 << 29) - 1), 25762306a36Sopenharmony_ci __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) 25862306a36Sopenharmony_ci : __clobber_all); 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ciSEC("socket") 26262306a36Sopenharmony_ci__description("bounds check after truncation of non-boundary-crossing range") 26362306a36Sopenharmony_ci__success __success_unpriv __retval(0) 26462306a36Sopenharmony_ci__naked void of_non_boundary_crossing_range(void) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci asm volatile (" \ 26762306a36Sopenharmony_ci r1 = 0; \ 26862306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 26962306a36Sopenharmony_ci r2 = r10; \ 27062306a36Sopenharmony_ci r2 += -8; \ 27162306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 27262306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 27362306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 27462306a36Sopenharmony_ci /* r1 = [0x00, 0xff] */ \ 27562306a36Sopenharmony_ci r1 = *(u8*)(r0 + 0); \ 27662306a36Sopenharmony_ci r2 = 1; \ 27762306a36Sopenharmony_ci /* r2 = 0x10'0000'0000 */ \ 27862306a36Sopenharmony_ci r2 <<= 36; \ 27962306a36Sopenharmony_ci /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */ \ 28062306a36Sopenharmony_ci r1 += r2; \ 28162306a36Sopenharmony_ci /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */ \ 28262306a36Sopenharmony_ci r1 += 0x7fffffff; \ 28362306a36Sopenharmony_ci /* r1 = [0x00, 0xff] */ \ 28462306a36Sopenharmony_ci w1 -= 0x7fffffff; \ 28562306a36Sopenharmony_ci /* r1 = 0 */ \ 28662306a36Sopenharmony_ci r1 >>= 8; \ 28762306a36Sopenharmony_ci /* no-op */ \ 28862306a36Sopenharmony_ci r0 += r1; \ 28962306a36Sopenharmony_ci /* access at offset 0 */ \ 29062306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 29162306a36Sopenharmony_cil0_%=: /* exit */ \ 29262306a36Sopenharmony_ci r0 = 0; \ 29362306a36Sopenharmony_ci exit; \ 29462306a36Sopenharmony_ci" : 29562306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 29662306a36Sopenharmony_ci __imm_addr(map_hash_8b) 29762306a36Sopenharmony_ci : __clobber_all); 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ciSEC("socket") 30162306a36Sopenharmony_ci__description("bounds check after truncation of boundary-crossing range (1)") 30262306a36Sopenharmony_ci__failure 30362306a36Sopenharmony_ci/* not actually fully unbounded, but the bound is very high */ 30462306a36Sopenharmony_ci__msg("value -4294967168 makes map_value pointer be out of bounds") 30562306a36Sopenharmony_ci__failure_unpriv 30662306a36Sopenharmony_ci__naked void of_boundary_crossing_range_1(void) 30762306a36Sopenharmony_ci{ 30862306a36Sopenharmony_ci asm volatile (" \ 30962306a36Sopenharmony_ci r1 = 0; \ 31062306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 31162306a36Sopenharmony_ci r2 = r10; \ 31262306a36Sopenharmony_ci r2 += -8; \ 31362306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 31462306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 31562306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 31662306a36Sopenharmony_ci /* r1 = [0x00, 0xff] */ \ 31762306a36Sopenharmony_ci r1 = *(u8*)(r0 + 0); \ 31862306a36Sopenharmony_ci r1 += %[__imm_0]; \ 31962306a36Sopenharmony_ci /* r1 = [0xffff'ff80, 0x1'0000'007f] */ \ 32062306a36Sopenharmony_ci r1 += %[__imm_0]; \ 32162306a36Sopenharmony_ci /* r1 = [0xffff'ff80, 0xffff'ffff] or \ 32262306a36Sopenharmony_ci * [0x0000'0000, 0x0000'007f] \ 32362306a36Sopenharmony_ci */ \ 32462306a36Sopenharmony_ci w1 += 0; \ 32562306a36Sopenharmony_ci r1 -= %[__imm_0]; \ 32662306a36Sopenharmony_ci /* r1 = [0x00, 0xff] or \ 32762306a36Sopenharmony_ci * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]\ 32862306a36Sopenharmony_ci */ \ 32962306a36Sopenharmony_ci r1 -= %[__imm_0]; \ 33062306a36Sopenharmony_ci /* error on OOB pointer computation */ \ 33162306a36Sopenharmony_ci r0 += r1; \ 33262306a36Sopenharmony_ci /* exit */ \ 33362306a36Sopenharmony_ci r0 = 0; \ 33462306a36Sopenharmony_cil0_%=: exit; \ 33562306a36Sopenharmony_ci" : 33662306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 33762306a36Sopenharmony_ci __imm_addr(map_hash_8b), 33862306a36Sopenharmony_ci __imm_const(__imm_0, 0xffffff80 >> 1) 33962306a36Sopenharmony_ci : __clobber_all); 34062306a36Sopenharmony_ci} 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ciSEC("socket") 34362306a36Sopenharmony_ci__description("bounds check after truncation of boundary-crossing range (2)") 34462306a36Sopenharmony_ci__failure __msg("value -4294967168 makes map_value pointer be out of bounds") 34562306a36Sopenharmony_ci__failure_unpriv 34662306a36Sopenharmony_ci__naked void of_boundary_crossing_range_2(void) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci asm volatile (" \ 34962306a36Sopenharmony_ci r1 = 0; \ 35062306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 35162306a36Sopenharmony_ci r2 = r10; \ 35262306a36Sopenharmony_ci r2 += -8; \ 35362306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 35462306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 35562306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 35662306a36Sopenharmony_ci /* r1 = [0x00, 0xff] */ \ 35762306a36Sopenharmony_ci r1 = *(u8*)(r0 + 0); \ 35862306a36Sopenharmony_ci r1 += %[__imm_0]; \ 35962306a36Sopenharmony_ci /* r1 = [0xffff'ff80, 0x1'0000'007f] */ \ 36062306a36Sopenharmony_ci r1 += %[__imm_0]; \ 36162306a36Sopenharmony_ci /* r1 = [0xffff'ff80, 0xffff'ffff] or \ 36262306a36Sopenharmony_ci * [0x0000'0000, 0x0000'007f] \ 36362306a36Sopenharmony_ci * difference to previous test: truncation via MOV32\ 36462306a36Sopenharmony_ci * instead of ALU32. \ 36562306a36Sopenharmony_ci */ \ 36662306a36Sopenharmony_ci w1 = w1; \ 36762306a36Sopenharmony_ci r1 -= %[__imm_0]; \ 36862306a36Sopenharmony_ci /* r1 = [0x00, 0xff] or \ 36962306a36Sopenharmony_ci * [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]\ 37062306a36Sopenharmony_ci */ \ 37162306a36Sopenharmony_ci r1 -= %[__imm_0]; \ 37262306a36Sopenharmony_ci /* error on OOB pointer computation */ \ 37362306a36Sopenharmony_ci r0 += r1; \ 37462306a36Sopenharmony_ci /* exit */ \ 37562306a36Sopenharmony_ci r0 = 0; \ 37662306a36Sopenharmony_cil0_%=: exit; \ 37762306a36Sopenharmony_ci" : 37862306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 37962306a36Sopenharmony_ci __imm_addr(map_hash_8b), 38062306a36Sopenharmony_ci __imm_const(__imm_0, 0xffffff80 >> 1) 38162306a36Sopenharmony_ci : __clobber_all); 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ciSEC("socket") 38562306a36Sopenharmony_ci__description("bounds check after wrapping 32-bit addition") 38662306a36Sopenharmony_ci__success __success_unpriv __retval(0) 38762306a36Sopenharmony_ci__naked void after_wrapping_32_bit_addition(void) 38862306a36Sopenharmony_ci{ 38962306a36Sopenharmony_ci asm volatile (" \ 39062306a36Sopenharmony_ci r1 = 0; \ 39162306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 39262306a36Sopenharmony_ci r2 = r10; \ 39362306a36Sopenharmony_ci r2 += -8; \ 39462306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 39562306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 39662306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 39762306a36Sopenharmony_ci /* r1 = 0x7fff'ffff */ \ 39862306a36Sopenharmony_ci r1 = 0x7fffffff; \ 39962306a36Sopenharmony_ci /* r1 = 0xffff'fffe */ \ 40062306a36Sopenharmony_ci r1 += 0x7fffffff; \ 40162306a36Sopenharmony_ci /* r1 = 0 */ \ 40262306a36Sopenharmony_ci w1 += 2; \ 40362306a36Sopenharmony_ci /* no-op */ \ 40462306a36Sopenharmony_ci r0 += r1; \ 40562306a36Sopenharmony_ci /* access at offset 0 */ \ 40662306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 40762306a36Sopenharmony_cil0_%=: /* exit */ \ 40862306a36Sopenharmony_ci r0 = 0; \ 40962306a36Sopenharmony_ci exit; \ 41062306a36Sopenharmony_ci" : 41162306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 41262306a36Sopenharmony_ci __imm_addr(map_hash_8b) 41362306a36Sopenharmony_ci : __clobber_all); 41462306a36Sopenharmony_ci} 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ciSEC("socket") 41762306a36Sopenharmony_ci__description("bounds check after shift with oversized count operand") 41862306a36Sopenharmony_ci__failure __msg("R0 max value is outside of the allowed memory range") 41962306a36Sopenharmony_ci__failure_unpriv 42062306a36Sopenharmony_ci__naked void shift_with_oversized_count_operand(void) 42162306a36Sopenharmony_ci{ 42262306a36Sopenharmony_ci asm volatile (" \ 42362306a36Sopenharmony_ci r1 = 0; \ 42462306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 42562306a36Sopenharmony_ci r2 = r10; \ 42662306a36Sopenharmony_ci r2 += -8; \ 42762306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 42862306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 42962306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 43062306a36Sopenharmony_ci r2 = 32; \ 43162306a36Sopenharmony_ci r1 = 1; \ 43262306a36Sopenharmony_ci /* r1 = (u32)1 << (u32)32 = ? */ \ 43362306a36Sopenharmony_ci w1 <<= w2; \ 43462306a36Sopenharmony_ci /* r1 = [0x0000, 0xffff] */ \ 43562306a36Sopenharmony_ci r1 &= 0xffff; \ 43662306a36Sopenharmony_ci /* computes unknown pointer, potentially OOB */ \ 43762306a36Sopenharmony_ci r0 += r1; \ 43862306a36Sopenharmony_ci /* potentially OOB access */ \ 43962306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 44062306a36Sopenharmony_cil0_%=: /* exit */ \ 44162306a36Sopenharmony_ci r0 = 0; \ 44262306a36Sopenharmony_ci exit; \ 44362306a36Sopenharmony_ci" : 44462306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 44562306a36Sopenharmony_ci __imm_addr(map_hash_8b) 44662306a36Sopenharmony_ci : __clobber_all); 44762306a36Sopenharmony_ci} 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ciSEC("socket") 45062306a36Sopenharmony_ci__description("bounds check after right shift of maybe-negative number") 45162306a36Sopenharmony_ci__failure __msg("R0 unbounded memory access") 45262306a36Sopenharmony_ci__failure_unpriv 45362306a36Sopenharmony_ci__naked void shift_of_maybe_negative_number(void) 45462306a36Sopenharmony_ci{ 45562306a36Sopenharmony_ci asm volatile (" \ 45662306a36Sopenharmony_ci r1 = 0; \ 45762306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 45862306a36Sopenharmony_ci r2 = r10; \ 45962306a36Sopenharmony_ci r2 += -8; \ 46062306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 46162306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 46262306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 46362306a36Sopenharmony_ci /* r1 = [0x00, 0xff] */ \ 46462306a36Sopenharmony_ci r1 = *(u8*)(r0 + 0); \ 46562306a36Sopenharmony_ci /* r1 = [-0x01, 0xfe] */ \ 46662306a36Sopenharmony_ci r1 -= 1; \ 46762306a36Sopenharmony_ci /* r1 = 0 or 0xff'ffff'ffff'ffff */ \ 46862306a36Sopenharmony_ci r1 >>= 8; \ 46962306a36Sopenharmony_ci /* r1 = 0 or 0xffff'ffff'ffff */ \ 47062306a36Sopenharmony_ci r1 >>= 8; \ 47162306a36Sopenharmony_ci /* computes unknown pointer, potentially OOB */ \ 47262306a36Sopenharmony_ci r0 += r1; \ 47362306a36Sopenharmony_ci /* potentially OOB access */ \ 47462306a36Sopenharmony_ci r0 = *(u8*)(r0 + 0); \ 47562306a36Sopenharmony_cil0_%=: /* exit */ \ 47662306a36Sopenharmony_ci r0 = 0; \ 47762306a36Sopenharmony_ci exit; \ 47862306a36Sopenharmony_ci" : 47962306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 48062306a36Sopenharmony_ci __imm_addr(map_hash_8b) 48162306a36Sopenharmony_ci : __clobber_all); 48262306a36Sopenharmony_ci} 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ciSEC("socket") 48562306a36Sopenharmony_ci__description("bounds check after 32-bit right shift with 64-bit input") 48662306a36Sopenharmony_ci__failure __msg("math between map_value pointer and 4294967294 is not allowed") 48762306a36Sopenharmony_ci__failure_unpriv 48862306a36Sopenharmony_ci__naked void shift_with_64_bit_input(void) 48962306a36Sopenharmony_ci{ 49062306a36Sopenharmony_ci asm volatile (" \ 49162306a36Sopenharmony_ci r1 = 0; \ 49262306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 49362306a36Sopenharmony_ci r2 = r10; \ 49462306a36Sopenharmony_ci r2 += -8; \ 49562306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 49662306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 49762306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 49862306a36Sopenharmony_ci r1 = 2; \ 49962306a36Sopenharmony_ci /* r1 = 1<<32 */ \ 50062306a36Sopenharmony_ci r1 <<= 31; \ 50162306a36Sopenharmony_ci /* r1 = 0 (NOT 2!) */ \ 50262306a36Sopenharmony_ci w1 >>= 31; \ 50362306a36Sopenharmony_ci /* r1 = 0xffff'fffe (NOT 0!) */ \ 50462306a36Sopenharmony_ci w1 -= 2; \ 50562306a36Sopenharmony_ci /* error on computing OOB pointer */ \ 50662306a36Sopenharmony_ci r0 += r1; \ 50762306a36Sopenharmony_ci /* exit */ \ 50862306a36Sopenharmony_ci r0 = 0; \ 50962306a36Sopenharmony_cil0_%=: exit; \ 51062306a36Sopenharmony_ci" : 51162306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 51262306a36Sopenharmony_ci __imm_addr(map_hash_8b) 51362306a36Sopenharmony_ci : __clobber_all); 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ciSEC("socket") 51762306a36Sopenharmony_ci__description("bounds check map access with off+size signed 32bit overflow. test1") 51862306a36Sopenharmony_ci__failure __msg("map_value pointer and 2147483646") 51962306a36Sopenharmony_ci__failure_unpriv 52062306a36Sopenharmony_ci__naked void size_signed_32bit_overflow_test1(void) 52162306a36Sopenharmony_ci{ 52262306a36Sopenharmony_ci asm volatile (" \ 52362306a36Sopenharmony_ci r1 = 0; \ 52462306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 52562306a36Sopenharmony_ci r2 = r10; \ 52662306a36Sopenharmony_ci r2 += -8; \ 52762306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 52862306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 52962306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 53062306a36Sopenharmony_ci exit; \ 53162306a36Sopenharmony_cil0_%=: r0 += 0x7ffffffe; \ 53262306a36Sopenharmony_ci r0 = *(u64*)(r0 + 0); \ 53362306a36Sopenharmony_ci goto l1_%=; \ 53462306a36Sopenharmony_cil1_%=: exit; \ 53562306a36Sopenharmony_ci" : 53662306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 53762306a36Sopenharmony_ci __imm_addr(map_hash_8b) 53862306a36Sopenharmony_ci : __clobber_all); 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ciSEC("socket") 54262306a36Sopenharmony_ci__description("bounds check map access with off+size signed 32bit overflow. test2") 54362306a36Sopenharmony_ci__failure __msg("pointer offset 1073741822") 54462306a36Sopenharmony_ci__msg_unpriv("R0 pointer arithmetic of map value goes out of range") 54562306a36Sopenharmony_ci__naked void size_signed_32bit_overflow_test2(void) 54662306a36Sopenharmony_ci{ 54762306a36Sopenharmony_ci asm volatile (" \ 54862306a36Sopenharmony_ci r1 = 0; \ 54962306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 55062306a36Sopenharmony_ci r2 = r10; \ 55162306a36Sopenharmony_ci r2 += -8; \ 55262306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 55362306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 55462306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 55562306a36Sopenharmony_ci exit; \ 55662306a36Sopenharmony_cil0_%=: r0 += 0x1fffffff; \ 55762306a36Sopenharmony_ci r0 += 0x1fffffff; \ 55862306a36Sopenharmony_ci r0 += 0x1fffffff; \ 55962306a36Sopenharmony_ci r0 = *(u64*)(r0 + 0); \ 56062306a36Sopenharmony_ci goto l1_%=; \ 56162306a36Sopenharmony_cil1_%=: exit; \ 56262306a36Sopenharmony_ci" : 56362306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 56462306a36Sopenharmony_ci __imm_addr(map_hash_8b) 56562306a36Sopenharmony_ci : __clobber_all); 56662306a36Sopenharmony_ci} 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ciSEC("socket") 56962306a36Sopenharmony_ci__description("bounds check map access with off+size signed 32bit overflow. test3") 57062306a36Sopenharmony_ci__failure __msg("pointer offset -1073741822") 57162306a36Sopenharmony_ci__msg_unpriv("R0 pointer arithmetic of map value goes out of range") 57262306a36Sopenharmony_ci__naked void size_signed_32bit_overflow_test3(void) 57362306a36Sopenharmony_ci{ 57462306a36Sopenharmony_ci asm volatile (" \ 57562306a36Sopenharmony_ci r1 = 0; \ 57662306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 57762306a36Sopenharmony_ci r2 = r10; \ 57862306a36Sopenharmony_ci r2 += -8; \ 57962306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 58062306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 58162306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 58262306a36Sopenharmony_ci exit; \ 58362306a36Sopenharmony_cil0_%=: r0 -= 0x1fffffff; \ 58462306a36Sopenharmony_ci r0 -= 0x1fffffff; \ 58562306a36Sopenharmony_ci r0 = *(u64*)(r0 + 2); \ 58662306a36Sopenharmony_ci goto l1_%=; \ 58762306a36Sopenharmony_cil1_%=: exit; \ 58862306a36Sopenharmony_ci" : 58962306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 59062306a36Sopenharmony_ci __imm_addr(map_hash_8b) 59162306a36Sopenharmony_ci : __clobber_all); 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ciSEC("socket") 59562306a36Sopenharmony_ci__description("bounds check map access with off+size signed 32bit overflow. test4") 59662306a36Sopenharmony_ci__failure __msg("map_value pointer and 1000000000000") 59762306a36Sopenharmony_ci__failure_unpriv 59862306a36Sopenharmony_ci__naked void size_signed_32bit_overflow_test4(void) 59962306a36Sopenharmony_ci{ 60062306a36Sopenharmony_ci asm volatile (" \ 60162306a36Sopenharmony_ci r1 = 0; \ 60262306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 60362306a36Sopenharmony_ci r2 = r10; \ 60462306a36Sopenharmony_ci r2 += -8; \ 60562306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 60662306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 60762306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 60862306a36Sopenharmony_ci exit; \ 60962306a36Sopenharmony_cil0_%=: r1 = 1000000; \ 61062306a36Sopenharmony_ci r1 *= 1000000; \ 61162306a36Sopenharmony_ci r0 += r1; \ 61262306a36Sopenharmony_ci r0 = *(u64*)(r0 + 2); \ 61362306a36Sopenharmony_ci goto l1_%=; \ 61462306a36Sopenharmony_cil1_%=: exit; \ 61562306a36Sopenharmony_ci" : 61662306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 61762306a36Sopenharmony_ci __imm_addr(map_hash_8b) 61862306a36Sopenharmony_ci : __clobber_all); 61962306a36Sopenharmony_ci} 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ciSEC("socket") 62262306a36Sopenharmony_ci__description("bounds check mixed 32bit and 64bit arithmetic. test1") 62362306a36Sopenharmony_ci__success __failure_unpriv __msg_unpriv("R0 invalid mem access 'scalar'") 62462306a36Sopenharmony_ci__retval(0) 62562306a36Sopenharmony_ci__naked void _32bit_and_64bit_arithmetic_test1(void) 62662306a36Sopenharmony_ci{ 62762306a36Sopenharmony_ci asm volatile (" \ 62862306a36Sopenharmony_ci r0 = 0; \ 62962306a36Sopenharmony_ci r1 = -1; \ 63062306a36Sopenharmony_ci r1 <<= 32; \ 63162306a36Sopenharmony_ci r1 += 1; \ 63262306a36Sopenharmony_ci /* r1 = 0xffffFFFF00000001 */ \ 63362306a36Sopenharmony_ci if w1 > 1 goto l0_%=; \ 63462306a36Sopenharmony_ci /* check ALU64 op keeps 32bit bounds */ \ 63562306a36Sopenharmony_ci r1 += 1; \ 63662306a36Sopenharmony_ci if w1 > 2 goto l0_%=; \ 63762306a36Sopenharmony_ci goto l1_%=; \ 63862306a36Sopenharmony_cil0_%=: /* invalid ldx if bounds are lost above */ \ 63962306a36Sopenharmony_ci r0 = *(u64*)(r0 - 1); \ 64062306a36Sopenharmony_cil1_%=: exit; \ 64162306a36Sopenharmony_ci" ::: __clobber_all); 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ciSEC("socket") 64562306a36Sopenharmony_ci__description("bounds check mixed 32bit and 64bit arithmetic. test2") 64662306a36Sopenharmony_ci__success __failure_unpriv __msg_unpriv("R0 invalid mem access 'scalar'") 64762306a36Sopenharmony_ci__retval(0) 64862306a36Sopenharmony_ci__naked void _32bit_and_64bit_arithmetic_test2(void) 64962306a36Sopenharmony_ci{ 65062306a36Sopenharmony_ci asm volatile (" \ 65162306a36Sopenharmony_ci r0 = 0; \ 65262306a36Sopenharmony_ci r1 = -1; \ 65362306a36Sopenharmony_ci r1 <<= 32; \ 65462306a36Sopenharmony_ci r1 += 1; \ 65562306a36Sopenharmony_ci /* r1 = 0xffffFFFF00000001 */ \ 65662306a36Sopenharmony_ci r2 = 3; \ 65762306a36Sopenharmony_ci /* r1 = 0x2 */ \ 65862306a36Sopenharmony_ci w1 += 1; \ 65962306a36Sopenharmony_ci /* check ALU32 op zero extends 64bit bounds */ \ 66062306a36Sopenharmony_ci if r1 > r2 goto l0_%=; \ 66162306a36Sopenharmony_ci goto l1_%=; \ 66262306a36Sopenharmony_cil0_%=: /* invalid ldx if bounds are lost above */ \ 66362306a36Sopenharmony_ci r0 = *(u64*)(r0 - 1); \ 66462306a36Sopenharmony_cil1_%=: exit; \ 66562306a36Sopenharmony_ci" ::: __clobber_all); 66662306a36Sopenharmony_ci} 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ciSEC("tc") 66962306a36Sopenharmony_ci__description("assigning 32bit bounds to 64bit for wA = 0, wB = wA") 67062306a36Sopenharmony_ci__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 67162306a36Sopenharmony_ci__naked void for_wa_0_wb_wa(void) 67262306a36Sopenharmony_ci{ 67362306a36Sopenharmony_ci asm volatile (" \ 67462306a36Sopenharmony_ci r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 67562306a36Sopenharmony_ci r7 = *(u32*)(r1 + %[__sk_buff_data]); \ 67662306a36Sopenharmony_ci w9 = 0; \ 67762306a36Sopenharmony_ci w2 = w9; \ 67862306a36Sopenharmony_ci r6 = r7; \ 67962306a36Sopenharmony_ci r6 += r2; \ 68062306a36Sopenharmony_ci r3 = r6; \ 68162306a36Sopenharmony_ci r3 += 8; \ 68262306a36Sopenharmony_ci if r3 > r8 goto l0_%=; \ 68362306a36Sopenharmony_ci r5 = *(u32*)(r6 + 0); \ 68462306a36Sopenharmony_cil0_%=: r0 = 0; \ 68562306a36Sopenharmony_ci exit; \ 68662306a36Sopenharmony_ci" : 68762306a36Sopenharmony_ci : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 68862306a36Sopenharmony_ci __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 68962306a36Sopenharmony_ci : __clobber_all); 69062306a36Sopenharmony_ci} 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ciSEC("socket") 69362306a36Sopenharmony_ci__description("bounds check for reg = 0, reg xor 1") 69462306a36Sopenharmony_ci__success __failure_unpriv 69562306a36Sopenharmony_ci__msg_unpriv("R0 min value is outside of the allowed memory range") 69662306a36Sopenharmony_ci__retval(0) 69762306a36Sopenharmony_ci__naked void reg_0_reg_xor_1(void) 69862306a36Sopenharmony_ci{ 69962306a36Sopenharmony_ci asm volatile (" \ 70062306a36Sopenharmony_ci r1 = 0; \ 70162306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 70262306a36Sopenharmony_ci r2 = r10; \ 70362306a36Sopenharmony_ci r2 += -8; \ 70462306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 70562306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 70662306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 70762306a36Sopenharmony_ci exit; \ 70862306a36Sopenharmony_cil0_%=: r1 = 0; \ 70962306a36Sopenharmony_ci r1 ^= 1; \ 71062306a36Sopenharmony_ci if r1 != 0 goto l1_%=; \ 71162306a36Sopenharmony_ci r0 = *(u64*)(r0 + 8); \ 71262306a36Sopenharmony_cil1_%=: r0 = 0; \ 71362306a36Sopenharmony_ci exit; \ 71462306a36Sopenharmony_ci" : 71562306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 71662306a36Sopenharmony_ci __imm_addr(map_hash_8b) 71762306a36Sopenharmony_ci : __clobber_all); 71862306a36Sopenharmony_ci} 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ciSEC("socket") 72162306a36Sopenharmony_ci__description("bounds check for reg32 = 0, reg32 xor 1") 72262306a36Sopenharmony_ci__success __failure_unpriv 72362306a36Sopenharmony_ci__msg_unpriv("R0 min value is outside of the allowed memory range") 72462306a36Sopenharmony_ci__retval(0) 72562306a36Sopenharmony_ci__naked void reg32_0_reg32_xor_1(void) 72662306a36Sopenharmony_ci{ 72762306a36Sopenharmony_ci asm volatile (" \ 72862306a36Sopenharmony_ci r1 = 0; \ 72962306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 73062306a36Sopenharmony_ci r2 = r10; \ 73162306a36Sopenharmony_ci r2 += -8; \ 73262306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 73362306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 73462306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 73562306a36Sopenharmony_ci exit; \ 73662306a36Sopenharmony_cil0_%=: w1 = 0; \ 73762306a36Sopenharmony_ci w1 ^= 1; \ 73862306a36Sopenharmony_ci if w1 != 0 goto l1_%=; \ 73962306a36Sopenharmony_ci r0 = *(u64*)(r0 + 8); \ 74062306a36Sopenharmony_cil1_%=: r0 = 0; \ 74162306a36Sopenharmony_ci exit; \ 74262306a36Sopenharmony_ci" : 74362306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 74462306a36Sopenharmony_ci __imm_addr(map_hash_8b) 74562306a36Sopenharmony_ci : __clobber_all); 74662306a36Sopenharmony_ci} 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ciSEC("socket") 74962306a36Sopenharmony_ci__description("bounds check for reg = 2, reg xor 3") 75062306a36Sopenharmony_ci__success __failure_unpriv 75162306a36Sopenharmony_ci__msg_unpriv("R0 min value is outside of the allowed memory range") 75262306a36Sopenharmony_ci__retval(0) 75362306a36Sopenharmony_ci__naked void reg_2_reg_xor_3(void) 75462306a36Sopenharmony_ci{ 75562306a36Sopenharmony_ci asm volatile (" \ 75662306a36Sopenharmony_ci r1 = 0; \ 75762306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 75862306a36Sopenharmony_ci r2 = r10; \ 75962306a36Sopenharmony_ci r2 += -8; \ 76062306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 76162306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 76262306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 76362306a36Sopenharmony_ci exit; \ 76462306a36Sopenharmony_cil0_%=: r1 = 2; \ 76562306a36Sopenharmony_ci r1 ^= 3; \ 76662306a36Sopenharmony_ci if r1 > 0 goto l1_%=; \ 76762306a36Sopenharmony_ci r0 = *(u64*)(r0 + 8); \ 76862306a36Sopenharmony_cil1_%=: r0 = 0; \ 76962306a36Sopenharmony_ci exit; \ 77062306a36Sopenharmony_ci" : 77162306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 77262306a36Sopenharmony_ci __imm_addr(map_hash_8b) 77362306a36Sopenharmony_ci : __clobber_all); 77462306a36Sopenharmony_ci} 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ciSEC("socket") 77762306a36Sopenharmony_ci__description("bounds check for reg = any, reg xor 3") 77862306a36Sopenharmony_ci__failure __msg("invalid access to map value") 77962306a36Sopenharmony_ci__msg_unpriv("invalid access to map value") 78062306a36Sopenharmony_ci__naked void reg_any_reg_xor_3(void) 78162306a36Sopenharmony_ci{ 78262306a36Sopenharmony_ci asm volatile (" \ 78362306a36Sopenharmony_ci r1 = 0; \ 78462306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 78562306a36Sopenharmony_ci r2 = r10; \ 78662306a36Sopenharmony_ci r2 += -8; \ 78762306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 78862306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 78962306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 79062306a36Sopenharmony_ci exit; \ 79162306a36Sopenharmony_cil0_%=: r1 = *(u64*)(r0 + 0); \ 79262306a36Sopenharmony_ci r1 ^= 3; \ 79362306a36Sopenharmony_ci if r1 != 0 goto l1_%=; \ 79462306a36Sopenharmony_ci r0 = *(u64*)(r0 + 8); \ 79562306a36Sopenharmony_cil1_%=: r0 = 0; \ 79662306a36Sopenharmony_ci exit; \ 79762306a36Sopenharmony_ci" : 79862306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 79962306a36Sopenharmony_ci __imm_addr(map_hash_8b) 80062306a36Sopenharmony_ci : __clobber_all); 80162306a36Sopenharmony_ci} 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ciSEC("socket") 80462306a36Sopenharmony_ci__description("bounds check for reg32 = any, reg32 xor 3") 80562306a36Sopenharmony_ci__failure __msg("invalid access to map value") 80662306a36Sopenharmony_ci__msg_unpriv("invalid access to map value") 80762306a36Sopenharmony_ci__naked void reg32_any_reg32_xor_3(void) 80862306a36Sopenharmony_ci{ 80962306a36Sopenharmony_ci asm volatile (" \ 81062306a36Sopenharmony_ci r1 = 0; \ 81162306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 81262306a36Sopenharmony_ci r2 = r10; \ 81362306a36Sopenharmony_ci r2 += -8; \ 81462306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 81562306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 81662306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 81762306a36Sopenharmony_ci exit; \ 81862306a36Sopenharmony_cil0_%=: r1 = *(u64*)(r0 + 0); \ 81962306a36Sopenharmony_ci w1 ^= 3; \ 82062306a36Sopenharmony_ci if w1 != 0 goto l1_%=; \ 82162306a36Sopenharmony_ci r0 = *(u64*)(r0 + 8); \ 82262306a36Sopenharmony_cil1_%=: r0 = 0; \ 82362306a36Sopenharmony_ci exit; \ 82462306a36Sopenharmony_ci" : 82562306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 82662306a36Sopenharmony_ci __imm_addr(map_hash_8b) 82762306a36Sopenharmony_ci : __clobber_all); 82862306a36Sopenharmony_ci} 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ciSEC("socket") 83162306a36Sopenharmony_ci__description("bounds check for reg > 0, reg xor 3") 83262306a36Sopenharmony_ci__success __failure_unpriv 83362306a36Sopenharmony_ci__msg_unpriv("R0 min value is outside of the allowed memory range") 83462306a36Sopenharmony_ci__retval(0) 83562306a36Sopenharmony_ci__naked void reg_0_reg_xor_3(void) 83662306a36Sopenharmony_ci{ 83762306a36Sopenharmony_ci asm volatile (" \ 83862306a36Sopenharmony_ci r1 = 0; \ 83962306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 84062306a36Sopenharmony_ci r2 = r10; \ 84162306a36Sopenharmony_ci r2 += -8; \ 84262306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 84362306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 84462306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 84562306a36Sopenharmony_ci exit; \ 84662306a36Sopenharmony_cil0_%=: r1 = *(u64*)(r0 + 0); \ 84762306a36Sopenharmony_ci if r1 <= 0 goto l1_%=; \ 84862306a36Sopenharmony_ci r1 ^= 3; \ 84962306a36Sopenharmony_ci if r1 >= 0 goto l1_%=; \ 85062306a36Sopenharmony_ci r0 = *(u64*)(r0 + 8); \ 85162306a36Sopenharmony_cil1_%=: r0 = 0; \ 85262306a36Sopenharmony_ci exit; \ 85362306a36Sopenharmony_ci" : 85462306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 85562306a36Sopenharmony_ci __imm_addr(map_hash_8b) 85662306a36Sopenharmony_ci : __clobber_all); 85762306a36Sopenharmony_ci} 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ciSEC("socket") 86062306a36Sopenharmony_ci__description("bounds check for reg32 > 0, reg32 xor 3") 86162306a36Sopenharmony_ci__success __failure_unpriv 86262306a36Sopenharmony_ci__msg_unpriv("R0 min value is outside of the allowed memory range") 86362306a36Sopenharmony_ci__retval(0) 86462306a36Sopenharmony_ci__naked void reg32_0_reg32_xor_3(void) 86562306a36Sopenharmony_ci{ 86662306a36Sopenharmony_ci asm volatile (" \ 86762306a36Sopenharmony_ci r1 = 0; \ 86862306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 86962306a36Sopenharmony_ci r2 = r10; \ 87062306a36Sopenharmony_ci r2 += -8; \ 87162306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 87262306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 87362306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 87462306a36Sopenharmony_ci exit; \ 87562306a36Sopenharmony_cil0_%=: r1 = *(u64*)(r0 + 0); \ 87662306a36Sopenharmony_ci if w1 <= 0 goto l1_%=; \ 87762306a36Sopenharmony_ci w1 ^= 3; \ 87862306a36Sopenharmony_ci if w1 >= 0 goto l1_%=; \ 87962306a36Sopenharmony_ci r0 = *(u64*)(r0 + 8); \ 88062306a36Sopenharmony_cil1_%=: r0 = 0; \ 88162306a36Sopenharmony_ci exit; \ 88262306a36Sopenharmony_ci" : 88362306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 88462306a36Sopenharmony_ci __imm_addr(map_hash_8b) 88562306a36Sopenharmony_ci : __clobber_all); 88662306a36Sopenharmony_ci} 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ciSEC("socket") 88962306a36Sopenharmony_ci__description("bounds checks after 32-bit truncation. test 1") 89062306a36Sopenharmony_ci__success __failure_unpriv __msg_unpriv("R0 leaks addr") 89162306a36Sopenharmony_ci__retval(0) 89262306a36Sopenharmony_ci__naked void _32_bit_truncation_test_1(void) 89362306a36Sopenharmony_ci{ 89462306a36Sopenharmony_ci asm volatile (" \ 89562306a36Sopenharmony_ci r1 = 0; \ 89662306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 89762306a36Sopenharmony_ci r2 = r10; \ 89862306a36Sopenharmony_ci r2 += -8; \ 89962306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 90062306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 90162306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 90262306a36Sopenharmony_ci r1 = *(u32*)(r0 + 0); \ 90362306a36Sopenharmony_ci /* This used to reduce the max bound to 0x7fffffff */\ 90462306a36Sopenharmony_ci if r1 == 0 goto l1_%=; \ 90562306a36Sopenharmony_ci if r1 > 0x7fffffff goto l0_%=; \ 90662306a36Sopenharmony_cil1_%=: r0 = 0; \ 90762306a36Sopenharmony_cil0_%=: exit; \ 90862306a36Sopenharmony_ci" : 90962306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 91062306a36Sopenharmony_ci __imm_addr(map_hash_8b) 91162306a36Sopenharmony_ci : __clobber_all); 91262306a36Sopenharmony_ci} 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ciSEC("socket") 91562306a36Sopenharmony_ci__description("bounds checks after 32-bit truncation. test 2") 91662306a36Sopenharmony_ci__success __failure_unpriv __msg_unpriv("R0 leaks addr") 91762306a36Sopenharmony_ci__retval(0) 91862306a36Sopenharmony_ci__naked void _32_bit_truncation_test_2(void) 91962306a36Sopenharmony_ci{ 92062306a36Sopenharmony_ci asm volatile (" \ 92162306a36Sopenharmony_ci r1 = 0; \ 92262306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 92362306a36Sopenharmony_ci r2 = r10; \ 92462306a36Sopenharmony_ci r2 += -8; \ 92562306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 92662306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 92762306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 92862306a36Sopenharmony_ci r1 = *(u32*)(r0 + 0); \ 92962306a36Sopenharmony_ci if r1 s< 1 goto l1_%=; \ 93062306a36Sopenharmony_ci if w1 s< 0 goto l0_%=; \ 93162306a36Sopenharmony_cil1_%=: r0 = 0; \ 93262306a36Sopenharmony_cil0_%=: exit; \ 93362306a36Sopenharmony_ci" : 93462306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 93562306a36Sopenharmony_ci __imm_addr(map_hash_8b) 93662306a36Sopenharmony_ci : __clobber_all); 93762306a36Sopenharmony_ci} 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ciSEC("xdp") 94062306a36Sopenharmony_ci__description("bound check with JMP_JLT for crossing 64-bit signed boundary") 94162306a36Sopenharmony_ci__success __retval(0) 94262306a36Sopenharmony_ci__naked void crossing_64_bit_signed_boundary_1(void) 94362306a36Sopenharmony_ci{ 94462306a36Sopenharmony_ci asm volatile (" \ 94562306a36Sopenharmony_ci r2 = *(u32*)(r1 + %[xdp_md_data]); \ 94662306a36Sopenharmony_ci r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ 94762306a36Sopenharmony_ci r1 = r2; \ 94862306a36Sopenharmony_ci r1 += 1; \ 94962306a36Sopenharmony_ci if r1 > r3 goto l0_%=; \ 95062306a36Sopenharmony_ci r1 = *(u8*)(r2 + 0); \ 95162306a36Sopenharmony_ci r0 = 0x7fffffffffffff10 ll; \ 95262306a36Sopenharmony_ci r1 += r0; \ 95362306a36Sopenharmony_ci r0 = 0x8000000000000000 ll; \ 95462306a36Sopenharmony_cil1_%=: r0 += 1; \ 95562306a36Sopenharmony_ci /* r1 unsigned range is [0x7fffffffffffff10, 0x800000000000000f] */\ 95662306a36Sopenharmony_ci if r0 < r1 goto l1_%=; \ 95762306a36Sopenharmony_cil0_%=: r0 = 0; \ 95862306a36Sopenharmony_ci exit; \ 95962306a36Sopenharmony_ci" : 96062306a36Sopenharmony_ci : __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), 96162306a36Sopenharmony_ci __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) 96262306a36Sopenharmony_ci : __clobber_all); 96362306a36Sopenharmony_ci} 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ciSEC("xdp") 96662306a36Sopenharmony_ci__description("bound check with JMP_JSLT for crossing 64-bit signed boundary") 96762306a36Sopenharmony_ci__success __retval(0) 96862306a36Sopenharmony_ci__naked void crossing_64_bit_signed_boundary_2(void) 96962306a36Sopenharmony_ci{ 97062306a36Sopenharmony_ci asm volatile (" \ 97162306a36Sopenharmony_ci r2 = *(u32*)(r1 + %[xdp_md_data]); \ 97262306a36Sopenharmony_ci r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ 97362306a36Sopenharmony_ci r1 = r2; \ 97462306a36Sopenharmony_ci r1 += 1; \ 97562306a36Sopenharmony_ci if r1 > r3 goto l0_%=; \ 97662306a36Sopenharmony_ci r1 = *(u8*)(r2 + 0); \ 97762306a36Sopenharmony_ci r0 = 0x7fffffffffffff10 ll; \ 97862306a36Sopenharmony_ci r1 += r0; \ 97962306a36Sopenharmony_ci r2 = 0x8000000000000fff ll; \ 98062306a36Sopenharmony_ci r0 = 0x8000000000000000 ll; \ 98162306a36Sopenharmony_cil1_%=: r0 += 1; \ 98262306a36Sopenharmony_ci if r0 s> r2 goto l0_%=; \ 98362306a36Sopenharmony_ci /* r1 signed range is [S64_MIN, S64_MAX] */ \ 98462306a36Sopenharmony_ci if r0 s< r1 goto l1_%=; \ 98562306a36Sopenharmony_ci r0 = 1; \ 98662306a36Sopenharmony_ci exit; \ 98762306a36Sopenharmony_cil0_%=: r0 = 0; \ 98862306a36Sopenharmony_ci exit; \ 98962306a36Sopenharmony_ci" : 99062306a36Sopenharmony_ci : __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), 99162306a36Sopenharmony_ci __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) 99262306a36Sopenharmony_ci : __clobber_all); 99362306a36Sopenharmony_ci} 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_ciSEC("xdp") 99662306a36Sopenharmony_ci__description("bound check for loop upper bound greater than U32_MAX") 99762306a36Sopenharmony_ci__success __retval(0) 99862306a36Sopenharmony_ci__naked void bound_greater_than_u32_max(void) 99962306a36Sopenharmony_ci{ 100062306a36Sopenharmony_ci asm volatile (" \ 100162306a36Sopenharmony_ci r2 = *(u32*)(r1 + %[xdp_md_data]); \ 100262306a36Sopenharmony_ci r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ 100362306a36Sopenharmony_ci r1 = r2; \ 100462306a36Sopenharmony_ci r1 += 1; \ 100562306a36Sopenharmony_ci if r1 > r3 goto l0_%=; \ 100662306a36Sopenharmony_ci r1 = *(u8*)(r2 + 0); \ 100762306a36Sopenharmony_ci r0 = 0x100000000 ll; \ 100862306a36Sopenharmony_ci r1 += r0; \ 100962306a36Sopenharmony_ci r0 = 0x100000000 ll; \ 101062306a36Sopenharmony_cil1_%=: r0 += 1; \ 101162306a36Sopenharmony_ci if r0 < r1 goto l1_%=; \ 101262306a36Sopenharmony_cil0_%=: r0 = 0; \ 101362306a36Sopenharmony_ci exit; \ 101462306a36Sopenharmony_ci" : 101562306a36Sopenharmony_ci : __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), 101662306a36Sopenharmony_ci __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) 101762306a36Sopenharmony_ci : __clobber_all); 101862306a36Sopenharmony_ci} 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ciSEC("xdp") 102162306a36Sopenharmony_ci__description("bound check with JMP32_JLT for crossing 32-bit signed boundary") 102262306a36Sopenharmony_ci__success __retval(0) 102362306a36Sopenharmony_ci__naked void crossing_32_bit_signed_boundary_1(void) 102462306a36Sopenharmony_ci{ 102562306a36Sopenharmony_ci asm volatile (" \ 102662306a36Sopenharmony_ci r2 = *(u32*)(r1 + %[xdp_md_data]); \ 102762306a36Sopenharmony_ci r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ 102862306a36Sopenharmony_ci r1 = r2; \ 102962306a36Sopenharmony_ci r1 += 1; \ 103062306a36Sopenharmony_ci if r1 > r3 goto l0_%=; \ 103162306a36Sopenharmony_ci r1 = *(u8*)(r2 + 0); \ 103262306a36Sopenharmony_ci w0 = 0x7fffff10; \ 103362306a36Sopenharmony_ci w1 += w0; \ 103462306a36Sopenharmony_ci w0 = 0x80000000; \ 103562306a36Sopenharmony_cil1_%=: w0 += 1; \ 103662306a36Sopenharmony_ci /* r1 unsigned range is [0, 0x8000000f] */ \ 103762306a36Sopenharmony_ci if w0 < w1 goto l1_%=; \ 103862306a36Sopenharmony_cil0_%=: r0 = 0; \ 103962306a36Sopenharmony_ci exit; \ 104062306a36Sopenharmony_ci" : 104162306a36Sopenharmony_ci : __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), 104262306a36Sopenharmony_ci __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) 104362306a36Sopenharmony_ci : __clobber_all); 104462306a36Sopenharmony_ci} 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ciSEC("xdp") 104762306a36Sopenharmony_ci__description("bound check with JMP32_JSLT for crossing 32-bit signed boundary") 104862306a36Sopenharmony_ci__success __retval(0) 104962306a36Sopenharmony_ci__naked void crossing_32_bit_signed_boundary_2(void) 105062306a36Sopenharmony_ci{ 105162306a36Sopenharmony_ci asm volatile (" \ 105262306a36Sopenharmony_ci r2 = *(u32*)(r1 + %[xdp_md_data]); \ 105362306a36Sopenharmony_ci r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ 105462306a36Sopenharmony_ci r1 = r2; \ 105562306a36Sopenharmony_ci r1 += 1; \ 105662306a36Sopenharmony_ci if r1 > r3 goto l0_%=; \ 105762306a36Sopenharmony_ci r1 = *(u8*)(r2 + 0); \ 105862306a36Sopenharmony_ci w0 = 0x7fffff10; \ 105962306a36Sopenharmony_ci w1 += w0; \ 106062306a36Sopenharmony_ci w2 = 0x80000fff; \ 106162306a36Sopenharmony_ci w0 = 0x80000000; \ 106262306a36Sopenharmony_cil1_%=: w0 += 1; \ 106362306a36Sopenharmony_ci if w0 s> w2 goto l0_%=; \ 106462306a36Sopenharmony_ci /* r1 signed range is [S32_MIN, S32_MAX] */ \ 106562306a36Sopenharmony_ci if w0 s< w1 goto l1_%=; \ 106662306a36Sopenharmony_ci r0 = 1; \ 106762306a36Sopenharmony_ci exit; \ 106862306a36Sopenharmony_cil0_%=: r0 = 0; \ 106962306a36Sopenharmony_ci exit; \ 107062306a36Sopenharmony_ci" : 107162306a36Sopenharmony_ci : __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), 107262306a36Sopenharmony_ci __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) 107362306a36Sopenharmony_ci : __clobber_all); 107462306a36Sopenharmony_ci} 107562306a36Sopenharmony_ci 107662306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 1077