162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Converted from tools/testing/selftests/bpf/verifier/and.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_ci#define MAX_ENTRIES 11 962306a36Sopenharmony_ci 1062306a36Sopenharmony_cistruct test_val { 1162306a36Sopenharmony_ci unsigned int index; 1262306a36Sopenharmony_ci int foo[MAX_ENTRIES]; 1362306a36Sopenharmony_ci}; 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct { 1662306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 1762306a36Sopenharmony_ci __uint(max_entries, 1); 1862306a36Sopenharmony_ci __type(key, long long); 1962306a36Sopenharmony_ci __type(value, struct test_val); 2062306a36Sopenharmony_ci} map_hash_48b SEC(".maps"); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ciSEC("socket") 2362306a36Sopenharmony_ci__description("invalid and of negative number") 2462306a36Sopenharmony_ci__failure __msg("R0 max value is outside of the allowed memory range") 2562306a36Sopenharmony_ci__failure_unpriv 2662306a36Sopenharmony_ci__flag(BPF_F_ANY_ALIGNMENT) 2762306a36Sopenharmony_ci__naked void invalid_and_of_negative_number(void) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci asm volatile (" \ 3062306a36Sopenharmony_ci r1 = 0; \ 3162306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 3262306a36Sopenharmony_ci r2 = r10; \ 3362306a36Sopenharmony_ci r2 += -8; \ 3462306a36Sopenharmony_ci r1 = %[map_hash_48b] ll; \ 3562306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 3662306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 3762306a36Sopenharmony_ci r1 = *(u8*)(r0 + 0); \ 3862306a36Sopenharmony_ci r1 &= -4; \ 3962306a36Sopenharmony_ci r1 <<= 2; \ 4062306a36Sopenharmony_ci r0 += r1; \ 4162306a36Sopenharmony_cil0_%=: r1 = %[test_val_foo]; \ 4262306a36Sopenharmony_ci *(u64*)(r0 + 0) = r1; \ 4362306a36Sopenharmony_ci exit; \ 4462306a36Sopenharmony_ci" : 4562306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 4662306a36Sopenharmony_ci __imm_addr(map_hash_48b), 4762306a36Sopenharmony_ci __imm_const(test_val_foo, offsetof(struct test_val, foo)) 4862306a36Sopenharmony_ci : __clobber_all); 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciSEC("socket") 5262306a36Sopenharmony_ci__description("invalid range check") 5362306a36Sopenharmony_ci__failure __msg("R0 max value is outside of the allowed memory range") 5462306a36Sopenharmony_ci__failure_unpriv 5562306a36Sopenharmony_ci__flag(BPF_F_ANY_ALIGNMENT) 5662306a36Sopenharmony_ci__naked void invalid_range_check(void) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci asm volatile (" \ 5962306a36Sopenharmony_ci r1 = 0; \ 6062306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 6162306a36Sopenharmony_ci r2 = r10; \ 6262306a36Sopenharmony_ci r2 += -8; \ 6362306a36Sopenharmony_ci r1 = %[map_hash_48b] ll; \ 6462306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 6562306a36Sopenharmony_ci if r0 == 0 goto l0_%=; \ 6662306a36Sopenharmony_ci r1 = *(u32*)(r0 + 0); \ 6762306a36Sopenharmony_ci r9 = 1; \ 6862306a36Sopenharmony_ci w1 %%= 2; \ 6962306a36Sopenharmony_ci w1 += 1; \ 7062306a36Sopenharmony_ci w9 &= w1; \ 7162306a36Sopenharmony_ci w9 += 1; \ 7262306a36Sopenharmony_ci w9 >>= 1; \ 7362306a36Sopenharmony_ci w3 = 1; \ 7462306a36Sopenharmony_ci w3 -= w9; \ 7562306a36Sopenharmony_ci w3 *= 0x10000000; \ 7662306a36Sopenharmony_ci r0 += r3; \ 7762306a36Sopenharmony_ci *(u32*)(r0 + 0) = r3; \ 7862306a36Sopenharmony_cil0_%=: r0 = r0; \ 7962306a36Sopenharmony_ci exit; \ 8062306a36Sopenharmony_ci" : 8162306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 8262306a36Sopenharmony_ci __imm_addr(map_hash_48b) 8362306a36Sopenharmony_ci : __clobber_all); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciSEC("socket") 8762306a36Sopenharmony_ci__description("check known subreg with unknown reg") 8862306a36Sopenharmony_ci__success __failure_unpriv __msg_unpriv("R1 !read_ok") 8962306a36Sopenharmony_ci__retval(0) 9062306a36Sopenharmony_ci__naked void known_subreg_with_unknown_reg(void) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci asm volatile (" \ 9362306a36Sopenharmony_ci call %[bpf_get_prandom_u32]; \ 9462306a36Sopenharmony_ci r0 <<= 32; \ 9562306a36Sopenharmony_ci r0 += 1; \ 9662306a36Sopenharmony_ci r0 &= 0xFFFF1234; \ 9762306a36Sopenharmony_ci /* Upper bits are unknown but AND above masks out 1 zero'ing lower bits */\ 9862306a36Sopenharmony_ci if w0 < 1 goto l0_%=; \ 9962306a36Sopenharmony_ci r1 = *(u32*)(r1 + 512); \ 10062306a36Sopenharmony_cil0_%=: r0 = 0; \ 10162306a36Sopenharmony_ci exit; \ 10262306a36Sopenharmony_ci" : 10362306a36Sopenharmony_ci : __imm(bpf_get_prandom_u32) 10462306a36Sopenharmony_ci : __clobber_all); 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 108