162587Sitojun// SPDX-License-Identifier: GPL-2.0 278064Sume/* Converted from tools/testing/selftests/bpf/verifier/helper_value_access.c */ 362587Sitojun 453541Sshin#include <linux/bpf.h> 553541Sshin#include <bpf/bpf_helpers.h> 653541Sshin#include "bpf_misc.h" 753541Sshin 853541Sshinstruct other_val { 953541Sshin long long foo; 1053541Sshin long long bar; 1153541Sshin}; 1253541Sshin 1353541Sshinstruct { 1453541Sshin __uint(type, BPF_MAP_TYPE_HASH); 1553541Sshin __uint(max_entries, 1); 1653541Sshin __type(key, long long); 1753541Sshin __type(value, struct other_val); 1853541Sshin} map_hash_16b SEC(".maps"); 1953541Sshin 2053541Sshin#define MAX_ENTRIES 11 2153541Sshin 2253541Sshinstruct test_val { 2353541Sshin unsigned int index; 2453541Sshin int foo[MAX_ENTRIES]; 2553541Sshin}; 2653541Sshin 2753541Sshinstruct { 2853541Sshin __uint(type, BPF_MAP_TYPE_HASH); 2953541Sshin __uint(max_entries, 1); 3053541Sshin __type(key, long long); 3162587Sitojun __type(value, struct test_val); 3262587Sitojun} map_hash_48b SEC(".maps"); 3362587Sitojun 3462587Sitojunstruct { 3562587Sitojun __uint(type, BPF_MAP_TYPE_HASH); 3653541Sshin __uint(max_entries, 1); 3762587Sitojun __type(key, long long); 3862587Sitojun __type(value, long long); 3962587Sitojun} map_hash_8b SEC(".maps"); 4062587Sitojun 4162587SitojunSEC("tracepoint") 4262587Sitojun__description("helper access to map: full range") 4362587Sitojun__success 4462587Sitojun__naked void access_to_map_full_range(void) 4562587Sitojun{ 4662587Sitojun asm volatile (" \ 4762587Sitojun r2 = r10; \ 4862587Sitojun r2 += -8; \ 4962587Sitojun r1 = 0; \ 5062587Sitojun *(u64*)(r2 + 0) = r1; \ 5162587Sitojun r1 = %[map_hash_48b] ll; \ 5262587Sitojun call %[bpf_map_lookup_elem]; \ 5362587Sitojun if r0 == 0 goto l0_%=; \ 5462587Sitojun r1 = r0; \ 5562587Sitojun r2 = %[sizeof_test_val]; \ 5662587Sitojun r3 = 0; \ 5762587Sitojun call %[bpf_probe_read_kernel]; \ 5862587Sitojunl0_%=: exit; \ 5962587Sitojun" : 6062587Sitojun : __imm(bpf_map_lookup_elem), 6162587Sitojun __imm(bpf_probe_read_kernel), 6262587Sitojun __imm_addr(map_hash_48b), 6362587Sitojun __imm_const(sizeof_test_val, sizeof(struct test_val)) 6462587Sitojun : __clobber_all); 6562587Sitojun} 6653541Sshin 6753541SshinSEC("tracepoint") 6853541Sshin__description("helper access to map: partial range") 6962587Sitojun__success 7053541Sshin__naked void access_to_map_partial_range(void) 7162587Sitojun{ 7262587Sitojun asm volatile (" \ 7353541Sshin r2 = r10; \ 7462587Sitojun r2 += -8; \ 7562587Sitojun r1 = 0; \ 7662587Sitojun *(u64*)(r2 + 0) = r1; \ 7762587Sitojun r1 = %[map_hash_48b] ll; \ 7862587Sitojun call %[bpf_map_lookup_elem]; \ 7962587Sitojun if r0 == 0 goto l0_%=; \ 8062587Sitojun r1 = r0; \ 8162587Sitojun r2 = 8; \ 8262587Sitojun r3 = 0; \ 8378064Sume call %[bpf_probe_read_kernel]; \ 8462587Sitojunl0_%=: exit; \ 8562587Sitojun" : 8662587Sitojun : __imm(bpf_map_lookup_elem), 8762587Sitojun __imm(bpf_probe_read_kernel), 8862587Sitojun __imm_addr(map_hash_48b) 8962587Sitojun : __clobber_all); 9062587Sitojun} 9162587Sitojun 9262587Sitojun/* Call a function taking a pointer and a size which doesn't allow the size to 9362587Sitojun * be zero (i.e. bpf_trace_printk() declares the second argument to be 9462587Sitojun * ARG_CONST_SIZE, not ARG_CONST_SIZE_OR_ZERO). We attempt to pass zero for the 9562587Sitojun * size and expect to fail. 9662587Sitojun */ 9762587SitojunSEC("tracepoint") 9862587Sitojun__description("helper access to map: empty range") 9962587Sitojun__failure __msg("R2 invalid zero-sized read: u64=[0,0]") 10062587Sitojun__naked void access_to_map_empty_range(void) 10162587Sitojun{ 10262587Sitojun asm volatile (" \ 10362587Sitojun r2 = r10; \ 10462587Sitojun r2 += -8; \ 10562587Sitojun r1 = 0; \ 10662587Sitojun *(u64*)(r2 + 0) = r1; \ 10762587Sitojun r1 = %[map_hash_48b] ll; \ 10862587Sitojun call %[bpf_map_lookup_elem]; \ 10962587Sitojun if r0 == 0 goto l0_%=; \ 11062587Sitojun r1 = r0; \ 11162587Sitojun r2 = 0; \ 11262587Sitojun call %[bpf_trace_printk]; \ 11362587Sitojunl0_%=: exit; \ 11462587Sitojun" : 11562587Sitojun : __imm(bpf_map_lookup_elem), 11662587Sitojun __imm(bpf_trace_printk), 11762587Sitojun __imm_addr(map_hash_48b) 11862587Sitojun : __clobber_all); 11962587Sitojun} 12062587Sitojun 12162587Sitojun/* Like the test above, but this time the size register is not known to be zero; 12262587Sitojun * its lower-bound is zero though, which is still unacceptable. 12362587Sitojun */ 12462587SitojunSEC("tracepoint") 12562587Sitojun__description("helper access to map: possibly-empty ange") 12662587Sitojun__failure __msg("R2 invalid zero-sized read: u64=[0,4]") 12778064Sume__naked void access_to_map_possibly_empty_range(void) 12878064Sume{ 12978064Sume asm volatile (" \ 13078064Sume r2 = r10; \ 13162587Sitojun r2 += -8; \ 13262587Sitojun r1 = 0; \ 13362587Sitojun *(u64*)(r2 + 0) = r1; \ 13462587Sitojun r1 = %[map_hash_48b] ll; \ 13562587Sitojun call %[bpf_map_lookup_elem]; \ 13662587Sitojun if r0 == 0 goto l0_%=; \ 13762587Sitojun r1 = r0; \ 13862587Sitojun /* Read an unknown value */ \ 13962587Sitojun r7 = *(u64*)(r0 + 0); \ 14062587Sitojun /* Make it small and positive, to avoid other errors */ \ 14162587Sitojun r7 &= 4; \ 14262587Sitojun r2 = 0; \ 14362587Sitojun r2 += r7; \ 14462587Sitojun call %[bpf_trace_printk]; \ 14562587Sitojunl0_%=: exit; \ 14662587Sitojun" : 14762587Sitojun : __imm(bpf_map_lookup_elem), 14862587Sitojun __imm(bpf_trace_printk), 14962587Sitojun __imm_addr(map_hash_48b) 15062587Sitojun : __clobber_all); 15162587Sitojun} 15278064Sume 15362587SitojunSEC("tracepoint") 15462587Sitojun__description("helper access to map: out-of-bound range") 15562587Sitojun__failure __msg("invalid access to map value, value_size=48 off=0 size=56") 15662587Sitojun__naked void map_out_of_bound_range(void) 15762587Sitojun{ 15862587Sitojun asm volatile (" \ 15962587Sitojun r2 = r10; \ 16062587Sitojun r2 += -8; \ 16162587Sitojun r1 = 0; \ 16262587Sitojun *(u64*)(r2 + 0) = r1; \ 16362587Sitojun r1 = %[map_hash_48b] ll; \ 16462587Sitojun call %[bpf_map_lookup_elem]; \ 16562587Sitojun if r0 == 0 goto l0_%=; \ 16662587Sitojun r1 = r0; \ 16762587Sitojun r2 = %[__imm_0]; \ 16862587Sitojun r3 = 0; \ 16962587Sitojun call %[bpf_probe_read_kernel]; \ 17078064Sumel0_%=: exit; \ 17162587Sitojun" : 17262587Sitojun : __imm(bpf_map_lookup_elem), 17362587Sitojun __imm(bpf_probe_read_kernel), 17462587Sitojun __imm_addr(map_hash_48b), 17562587Sitojun __imm_const(__imm_0, sizeof(struct test_val) + 8) 17662587Sitojun : __clobber_all); 17762587Sitojun} 17862587Sitojun 17962587SitojunSEC("tracepoint") 18062587Sitojun__description("helper access to map: negative range") 18162587Sitojun__failure __msg("R2 min value is negative") 18262587Sitojun__naked void access_to_map_negative_range(void) 18362587Sitojun{ 18462587Sitojun asm volatile (" \ 18578064Sume r2 = r10; \ 18662587Sitojun r2 += -8; \ 18762587Sitojun r1 = 0; \ 18862587Sitojun *(u64*)(r2 + 0) = r1; \ 18962587Sitojun r1 = %[map_hash_48b] ll; \ 19062587Sitojun call %[bpf_map_lookup_elem]; \ 19162587Sitojun if r0 == 0 goto l0_%=; \ 19262587Sitojun r1 = r0; \ 19362587Sitojun r2 = -8; \ 19462587Sitojun r3 = 0; \ 19562587Sitojun call %[bpf_probe_read_kernel]; \ 19662587Sitojunl0_%=: exit; \ 19778064Sume" : 19862587Sitojun : __imm(bpf_map_lookup_elem), 19962587Sitojun __imm(bpf_probe_read_kernel), 20062587Sitojun __imm_addr(map_hash_48b) 20162587Sitojun : __clobber_all); 20262587Sitojun} 20362587Sitojun 20462587SitojunSEC("tracepoint") 20562587Sitojun__description("helper access to adjusted map (via const imm): full range") 20678064Sume__success 20778064Sume__naked void via_const_imm_full_range(void) 20878064Sume{ 20978064Sume asm volatile (" \ 21078064Sume r2 = r10; \ 21178064Sume r2 += -8; \ 21278064Sume r1 = 0; \ 21378064Sume *(u64*)(r2 + 0) = r1; \ 21478064Sume r1 = %[map_hash_48b] ll; \ 21578064Sume call %[bpf_map_lookup_elem]; \ 21678064Sume if r0 == 0 goto l0_%=; \ 21778064Sume r1 = r0; \ 21878064Sume r1 += %[test_val_foo]; \ 21962587Sitojun r2 = %[__imm_0]; \ 22062587Sitojun r3 = 0; \ 22162587Sitojun call %[bpf_probe_read_kernel]; \ 22262587Sitojunl0_%=: exit; \ 22362587Sitojun" : 22462587Sitojun : __imm(bpf_map_lookup_elem), 22578064Sume __imm(bpf_probe_read_kernel), 22662587Sitojun __imm_addr(map_hash_48b), 22762587Sitojun __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)), 22862587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 22962587Sitojun : __clobber_all); 23062587Sitojun} 23162587Sitojun 23262587SitojunSEC("tracepoint") 23362587Sitojun__description("helper access to adjusted map (via const imm): partial range") 23462587Sitojun__success 23562587Sitojun__naked void via_const_imm_partial_range(void) 23678064Sume{ 23762587Sitojun asm volatile (" \ 23862587Sitojun r2 = r10; \ 23962587Sitojun r2 += -8; \ 24062587Sitojun r1 = 0; \ 24162587Sitojun *(u64*)(r2 + 0) = r1; \ 24262587Sitojun r1 = %[map_hash_48b] ll; \ 24362587Sitojun call %[bpf_map_lookup_elem]; \ 24462587Sitojun if r0 == 0 goto l0_%=; \ 24562587Sitojun r1 = r0; \ 24662587Sitojun r1 += %[test_val_foo]; \ 24762587Sitojun r2 = 8; \ 24862587Sitojun r3 = 0; \ 24962587Sitojun call %[bpf_probe_read_kernel]; \ 25062587Sitojunl0_%=: exit; \ 25162587Sitojun" : 25262587Sitojun : __imm(bpf_map_lookup_elem), 25362587Sitojun __imm(bpf_probe_read_kernel), 25462587Sitojun __imm_addr(map_hash_48b), 25562587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 25662587Sitojun : __clobber_all); 25762587Sitojun} 25862587Sitojun 25978064SumeSEC("tracepoint") 26062587Sitojun__description("helper access to adjusted map (via const imm): empty range") 26162587Sitojun__failure __msg("R2 invalid zero-sized read") 26262587Sitojun__naked void via_const_imm_empty_range(void) 26362587Sitojun{ 26462587Sitojun asm volatile (" \ 26562587Sitojun r2 = r10; \ 26662587Sitojun r2 += -8; \ 26762587Sitojun r1 = 0; \ 26862587Sitojun *(u64*)(r2 + 0) = r1; \ 26962587Sitojun r1 = %[map_hash_48b] ll; \ 27078064Sume call %[bpf_map_lookup_elem]; \ 27162587Sitojun if r0 == 0 goto l0_%=; \ 27262587Sitojun r1 = r0; \ 27362587Sitojun r1 += %[test_val_foo]; \ 27462587Sitojun r2 = 0; \ 27562587Sitojun call %[bpf_trace_printk]; \ 27662587Sitojunl0_%=: exit; \ 27778064Sume" : 27862587Sitojun : __imm(bpf_map_lookup_elem), 27962587Sitojun __imm(bpf_trace_printk), 28062587Sitojun __imm_addr(map_hash_48b), 28162587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 28262587Sitojun : __clobber_all); 28362587Sitojun} 28462587Sitojun 28562587SitojunSEC("tracepoint") 28662587Sitojun__description("helper access to adjusted map (via const imm): out-of-bound range") 28762587Sitojun__failure __msg("invalid access to map value, value_size=48 off=4 size=52") 28878064Sume__naked void imm_out_of_bound_range(void) 28962587Sitojun{ 29062587Sitojun asm volatile (" \ 29162587Sitojun r2 = r10; \ 29262587Sitojun r2 += -8; \ 29362587Sitojun r1 = 0; \ 29462587Sitojun *(u64*)(r2 + 0) = r1; \ 29562587Sitojun r1 = %[map_hash_48b] ll; \ 29662587Sitojun call %[bpf_map_lookup_elem]; \ 29762587Sitojun if r0 == 0 goto l0_%=; \ 29862587Sitojun r1 = r0; \ 29978064Sume r1 += %[test_val_foo]; \ 30062587Sitojun r2 = %[__imm_0]; \ 30162587Sitojun r3 = 0; \ 30262587Sitojun call %[bpf_probe_read_kernel]; \ 30362587Sitojunl0_%=: exit; \ 30462587Sitojun" : 30562587Sitojun : __imm(bpf_map_lookup_elem), 30678064Sume __imm(bpf_probe_read_kernel), 30762587Sitojun __imm_addr(map_hash_48b), 30878064Sume __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 8), 30978064Sume __imm_const(test_val_foo, offsetof(struct test_val, foo)) 31078064Sume : __clobber_all); 31178064Sume} 31278064Sume 31378064SumeSEC("tracepoint") 31478064Sume__description("helper access to adjusted map (via const imm): negative range (> adjustment)") 31578064Sume__failure __msg("R2 min value is negative") 31662587Sitojun__naked void const_imm_negative_range_adjustment_1(void) 31762587Sitojun{ 31862587Sitojun asm volatile (" \ 31962587Sitojun r2 = r10; \ 32062587Sitojun r2 += -8; \ 32162587Sitojun r1 = 0; \ 32262587Sitojun *(u64*)(r2 + 0) = r1; \ 32362587Sitojun r1 = %[map_hash_48b] ll; \ 32462587Sitojun call %[bpf_map_lookup_elem]; \ 32562587Sitojun if r0 == 0 goto l0_%=; \ 32662587Sitojun r1 = r0; \ 32762587Sitojun r1 += %[test_val_foo]; \ 32862587Sitojun r2 = -8; \ 32978064Sume r3 = 0; \ 33062587Sitojun call %[bpf_probe_read_kernel]; \ 33162587Sitojunl0_%=: exit; \ 33262587Sitojun" : 33362587Sitojun : __imm(bpf_map_lookup_elem), 33462587Sitojun __imm(bpf_probe_read_kernel), 33562587Sitojun __imm_addr(map_hash_48b), 33662587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 33762587Sitojun : __clobber_all); 33878064Sume} 33962587Sitojun 34062587SitojunSEC("tracepoint") 34162587Sitojun__description("helper access to adjusted map (via const imm): negative range (< adjustment)") 34262587Sitojun__failure __msg("R2 min value is negative") 34362587Sitojun__naked void const_imm_negative_range_adjustment_2(void) 34462587Sitojun{ 34562587Sitojun asm volatile (" \ 34662587Sitojun r2 = r10; \ 34762587Sitojun r2 += -8; \ 34878064Sume r1 = 0; \ 34978064Sume *(u64*)(r2 + 0) = r1; \ 35078064Sume r1 = %[map_hash_48b] ll; \ 35178064Sume call %[bpf_map_lookup_elem]; \ 35262587Sitojun if r0 == 0 goto l0_%=; \ 35362587Sitojun r1 = r0; \ 35462587Sitojun r1 += %[test_val_foo]; \ 35562587Sitojun r2 = -1; \ 35662587Sitojun r3 = 0; \ 35762587Sitojun call %[bpf_probe_read_kernel]; \ 35862587Sitojunl0_%=: exit; \ 35962587Sitojun" : 36062587Sitojun : __imm(bpf_map_lookup_elem), 36162587Sitojun __imm(bpf_probe_read_kernel), 36262587Sitojun __imm_addr(map_hash_48b), 36362587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 36462587Sitojun : __clobber_all); 36562587Sitojun} 36662587Sitojun 36762587SitojunSEC("tracepoint") 36862587Sitojun__description("helper access to adjusted map (via const reg): full range") 36962587Sitojun__success 37062587Sitojun__naked void via_const_reg_full_range(void) 37162587Sitojun{ 37262587Sitojun asm volatile (" \ 37362587Sitojun r2 = r10; \ 37462587Sitojun r2 += -8; \ 37562587Sitojun r1 = 0; \ 37662587Sitojun *(u64*)(r2 + 0) = r1; \ 37762587Sitojun r1 = %[map_hash_48b] ll; \ 37862587Sitojun call %[bpf_map_lookup_elem]; \ 37962587Sitojun if r0 == 0 goto l0_%=; \ 38062587Sitojun r1 = r0; \ 38162587Sitojun r3 = %[test_val_foo]; \ 38262587Sitojun r1 += r3; \ 38362587Sitojun r2 = %[__imm_0]; \ 38462587Sitojun r3 = 0; \ 38562587Sitojun call %[bpf_probe_read_kernel]; \ 38662587Sitojunl0_%=: exit; \ 38762587Sitojun" : 38862587Sitojun : __imm(bpf_map_lookup_elem), 38962587Sitojun __imm(bpf_probe_read_kernel), 39062587Sitojun __imm_addr(map_hash_48b), 39162587Sitojun __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)), 39262587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 39362587Sitojun : __clobber_all); 39462587Sitojun} 39562587Sitojun 39662587SitojunSEC("tracepoint") 39762587Sitojun__description("helper access to adjusted map (via const reg): partial range") 39862587Sitojun__success 39962587Sitojun__naked void via_const_reg_partial_range(void) 40062587Sitojun{ 40178064Sume asm volatile (" \ 40262587Sitojun r2 = r10; \ 40362587Sitojun r2 += -8; \ 40462587Sitojun r1 = 0; \ 40562587Sitojun *(u64*)(r2 + 0) = r1; \ 40662587Sitojun r1 = %[map_hash_48b] ll; \ 40762587Sitojun call %[bpf_map_lookup_elem]; \ 40862587Sitojun if r0 == 0 goto l0_%=; \ 40962587Sitojun r1 = r0; \ 41062587Sitojun r3 = %[test_val_foo]; \ 41162587Sitojun r1 += r3; \ 41278064Sume r2 = 8; \ 41362587Sitojun r3 = 0; \ 41478064Sume call %[bpf_probe_read_kernel]; \ 41578064Sumel0_%=: exit; \ 41678064Sume" : 41778064Sume : __imm(bpf_map_lookup_elem), 41878064Sume __imm(bpf_probe_read_kernel), 41978064Sume __imm_addr(map_hash_48b), 42062587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 42162587Sitojun : __clobber_all); 42262587Sitojun} 42362587Sitojun 42462587SitojunSEC("tracepoint") 42562587Sitojun__description("helper access to adjusted map (via const reg): empty range") 42662587Sitojun__failure __msg("R2 invalid zero-sized read") 42762587Sitojun__naked void via_const_reg_empty_range(void) 42862587Sitojun{ 42962587Sitojun asm volatile (" \ 43062587Sitojun r2 = r10; \ 43162587Sitojun r2 += -8; \ 43262587Sitojun r1 = 0; \ 43362587Sitojun *(u64*)(r2 + 0) = r1; \ 43478064Sume r1 = %[map_hash_48b] ll; \ 43562587Sitojun call %[bpf_map_lookup_elem]; \ 43662587Sitojun if r0 == 0 goto l0_%=; \ 43762587Sitojun r1 = r0; \ 43862587Sitojun r3 = 0; \ 43962587Sitojun r1 += r3; \ 44062587Sitojun r2 = 0; \ 44162587Sitojun call %[bpf_trace_printk]; \ 44262587Sitojunl0_%=: exit; \ 44362587Sitojun" : 44462587Sitojun : __imm(bpf_map_lookup_elem), 44562587Sitojun __imm(bpf_trace_printk), 44662587Sitojun __imm_addr(map_hash_48b) 44762587Sitojun : __clobber_all); 44862587Sitojun} 44962587Sitojun 45078064SumeSEC("tracepoint") 45162587Sitojun__description("helper access to adjusted map (via const reg): out-of-bound range") 45262587Sitojun__failure __msg("invalid access to map value, value_size=48 off=4 size=52") 45362587Sitojun__naked void reg_out_of_bound_range(void) 45462587Sitojun{ 45562587Sitojun asm volatile (" \ 45662587Sitojun r2 = r10; \ 45762587Sitojun r2 += -8; \ 45862587Sitojun r1 = 0; \ 45962587Sitojun *(u64*)(r2 + 0) = r1; \ 46062587Sitojun r1 = %[map_hash_48b] ll; \ 46162587Sitojun call %[bpf_map_lookup_elem]; \ 46262587Sitojun if r0 == 0 goto l0_%=; \ 46362587Sitojun r1 = r0; \ 46462587Sitojun r3 = %[test_val_foo]; \ 46562587Sitojun r1 += r3; \ 46662587Sitojun r2 = %[__imm_0]; \ 46762587Sitojun r3 = 0; \ 46878064Sume call %[bpf_probe_read_kernel]; \ 46962587Sitojunl0_%=: exit; \ 47062587Sitojun" : 47162587Sitojun : __imm(bpf_map_lookup_elem), 47262587Sitojun __imm(bpf_probe_read_kernel), 47378064Sume __imm_addr(map_hash_48b), 47478064Sume __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 8), 47562587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 47662587Sitojun : __clobber_all); 47762587Sitojun} 47862587Sitojun 47962587SitojunSEC("tracepoint") 48062587Sitojun__description("helper access to adjusted map (via const reg): negative range (> adjustment)") 48162587Sitojun__failure __msg("R2 min value is negative") 48262587Sitojun__naked void const_reg_negative_range_adjustment_1(void) 48362587Sitojun{ 48462587Sitojun asm volatile (" \ 48562587Sitojun r2 = r10; \ 48662587Sitojun r2 += -8; \ 48762587Sitojun r1 = 0; \ 48862587Sitojun *(u64*)(r2 + 0) = r1; \ 48962587Sitojun r1 = %[map_hash_48b] ll; \ 49062587Sitojun call %[bpf_map_lookup_elem]; \ 49162587Sitojun if r0 == 0 goto l0_%=; \ 49262587Sitojun r1 = r0; \ 49362587Sitojun r3 = %[test_val_foo]; \ 49462587Sitojun r1 += r3; \ 49562587Sitojun r2 = -8; \ 49662587Sitojun r3 = 0; \ 49762587Sitojun call %[bpf_probe_read_kernel]; \ 49862587Sitojunl0_%=: exit; \ 49962587Sitojun" : 50062587Sitojun : __imm(bpf_map_lookup_elem), 50162587Sitojun __imm(bpf_probe_read_kernel), 50262587Sitojun __imm_addr(map_hash_48b), 50362587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 50462587Sitojun : __clobber_all); 50562587Sitojun} 50662587Sitojun 50762587SitojunSEC("tracepoint") 50862587Sitojun__description("helper access to adjusted map (via const reg): negative range (< adjustment)") 50962587Sitojun__failure __msg("R2 min value is negative") 51062587Sitojun__naked void const_reg_negative_range_adjustment_2(void) 51162587Sitojun{ 51262587Sitojun asm volatile (" \ 51362587Sitojun r2 = r10; \ 51462587Sitojun r2 += -8; \ 51562587Sitojun r1 = 0; \ 51662587Sitojun *(u64*)(r2 + 0) = r1; \ 51762587Sitojun r1 = %[map_hash_48b] ll; \ 51862587Sitojun call %[bpf_map_lookup_elem]; \ 51962587Sitojun if r0 == 0 goto l0_%=; \ 52062587Sitojun r1 = r0; \ 52162587Sitojun r3 = %[test_val_foo]; \ 52262587Sitojun r1 += r3; \ 52362587Sitojun r2 = -1; \ 52462587Sitojun r3 = 0; \ 52562587Sitojun call %[bpf_probe_read_kernel]; \ 52662587Sitojunl0_%=: exit; \ 52762587Sitojun" : 52862587Sitojun : __imm(bpf_map_lookup_elem), 52962587Sitojun __imm(bpf_probe_read_kernel), 53062587Sitojun __imm_addr(map_hash_48b), 53162587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 53262587Sitojun : __clobber_all); 53362587Sitojun} 53462587Sitojun 53562587SitojunSEC("tracepoint") 53662587Sitojun__description("helper access to adjusted map (via variable): full range") 53762587Sitojun__success 53862587Sitojun__naked void map_via_variable_full_range(void) 53962587Sitojun{ 54062587Sitojun asm volatile (" \ 54162587Sitojun r2 = r10; \ 54262587Sitojun r2 += -8; \ 54362587Sitojun r1 = 0; \ 54462587Sitojun *(u64*)(r2 + 0) = r1; \ 54562587Sitojun r1 = %[map_hash_48b] ll; \ 54662587Sitojun call %[bpf_map_lookup_elem]; \ 54762587Sitojun if r0 == 0 goto l0_%=; \ 54862587Sitojun r1 = r0; \ 54962587Sitojun r3 = *(u32*)(r0 + 0); \ 55062587Sitojun if r3 > %[test_val_foo] goto l0_%=; \ 55162587Sitojun r1 += r3; \ 55262587Sitojun r2 = %[__imm_0]; \ 55362587Sitojun r3 = 0; \ 55462587Sitojun call %[bpf_probe_read_kernel]; \ 55562587Sitojunl0_%=: exit; \ 55662587Sitojun" : 55762587Sitojun : __imm(bpf_map_lookup_elem), 55862587Sitojun __imm(bpf_probe_read_kernel), 55962587Sitojun __imm_addr(map_hash_48b), 56062587Sitojun __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)), 56162587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 56262587Sitojun : __clobber_all); 56362587Sitojun} 56478064Sume 56578064SumeSEC("tracepoint") 56678064Sume__description("helper access to adjusted map (via variable): partial range") 56778064Sume__success 56878064Sume__naked void map_via_variable_partial_range(void) 56978064Sume{ 57078064Sume asm volatile (" \ 57162587Sitojun r2 = r10; \ 57262587Sitojun r2 += -8; \ 57362587Sitojun r1 = 0; \ 57462587Sitojun *(u64*)(r2 + 0) = r1; \ 57562587Sitojun r1 = %[map_hash_48b] ll; \ 57662587Sitojun call %[bpf_map_lookup_elem]; \ 57762587Sitojun if r0 == 0 goto l0_%=; \ 57862587Sitojun r1 = r0; \ 57978064Sume r3 = *(u32*)(r0 + 0); \ 58062587Sitojun if r3 > %[test_val_foo] goto l0_%=; \ 58178064Sume r1 += r3; \ 58262587Sitojun r2 = 8; \ 58362587Sitojun r3 = 0; \ 58462587Sitojun call %[bpf_probe_read_kernel]; \ 58562587Sitojunl0_%=: exit; \ 58662587Sitojun" : 58762587Sitojun : __imm(bpf_map_lookup_elem), 58862587Sitojun __imm(bpf_probe_read_kernel), 58962587Sitojun __imm_addr(map_hash_48b), 59062587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 59178064Sume : __clobber_all); 59278064Sume} 59378064Sume 59478064SumeSEC("tracepoint") 59578064Sume__description("helper access to adjusted map (via variable): empty range") 59678064Sume__failure __msg("R2 invalid zero-sized read") 59762587Sitojun__naked void map_via_variable_empty_range(void) 59862587Sitojun{ 59962587Sitojun asm volatile (" \ 60062587Sitojun r2 = r10; \ 60162587Sitojun r2 += -8; \ 60262587Sitojun r1 = 0; \ 60362587Sitojun *(u64*)(r2 + 0) = r1; \ 60478064Sume r1 = %[map_hash_48b] ll; \ 60562587Sitojun call %[bpf_map_lookup_elem]; \ 60662587Sitojun if r0 == 0 goto l0_%=; \ 60762587Sitojun r1 = r0; \ 60862587Sitojun r3 = *(u32*)(r0 + 0); \ 60962587Sitojun if r3 > %[test_val_foo] goto l0_%=; \ 61062587Sitojun r1 += r3; \ 61162587Sitojun r2 = 0; \ 61262587Sitojun call %[bpf_trace_printk]; \ 61362587Sitojunl0_%=: exit; \ 61462587Sitojun" : 61578064Sume : __imm(bpf_map_lookup_elem), 61678064Sume __imm(bpf_trace_printk), 61778064Sume __imm_addr(map_hash_48b), 61878064Sume __imm_const(test_val_foo, offsetof(struct test_val, foo)) 61978064Sume : __clobber_all); 62062587Sitojun} 62162587Sitojun 62262587SitojunSEC("tracepoint") 62362587Sitojun__description("helper access to adjusted map (via variable): no max check") 62462587Sitojun__failure __msg("R1 unbounded memory access") 62562587Sitojun__naked void via_variable_no_max_check_1(void) 62662587Sitojun{ 62762587Sitojun asm volatile (" \ 62862587Sitojun r2 = r10; \ 62962587Sitojun r2 += -8; \ 63062587Sitojun r1 = 0; \ 63162587Sitojun *(u64*)(r2 + 0) = r1; \ 63262587Sitojun r1 = %[map_hash_48b] ll; \ 63362587Sitojun call %[bpf_map_lookup_elem]; \ 63462587Sitojun if r0 == 0 goto l0_%=; \ 63562587Sitojun r1 = r0; \ 63662587Sitojun r3 = *(u32*)(r0 + 0); \ 63762587Sitojun r1 += r3; \ 63862587Sitojun r2 = 1; \ 63962587Sitojun r3 = 0; \ 64078064Sume call %[bpf_probe_read_kernel]; \ 64178064Sumel0_%=: exit; \ 64278064Sume" : 64362587Sitojun : __imm(bpf_map_lookup_elem), 64462587Sitojun __imm(bpf_probe_read_kernel), 64562587Sitojun __imm_addr(map_hash_48b) 64662587Sitojun : __clobber_all); 64762587Sitojun} 64862587Sitojun 64962587SitojunSEC("tracepoint") 65062587Sitojun__description("helper access to adjusted map (via variable): wrong max check") 65162587Sitojun__failure __msg("invalid access to map value, value_size=48 off=4 size=45") 65262587Sitojun__naked void via_variable_wrong_max_check_1(void) 65362587Sitojun{ 65462587Sitojun asm volatile (" \ 65562587Sitojun r2 = r10; \ 65662587Sitojun r2 += -8; \ 65762587Sitojun r1 = 0; \ 65862587Sitojun *(u64*)(r2 + 0) = r1; \ 65962587Sitojun r1 = %[map_hash_48b] ll; \ 66062587Sitojun call %[bpf_map_lookup_elem]; \ 66162587Sitojun if r0 == 0 goto l0_%=; \ 66262587Sitojun r1 = r0; \ 66362587Sitojun r3 = *(u32*)(r0 + 0); \ 66462587Sitojun if r3 > %[test_val_foo] goto l0_%=; \ 66562587Sitojun r1 += r3; \ 66662587Sitojun r2 = %[__imm_0]; \ 66762587Sitojun r3 = 0; \ 66862587Sitojun call %[bpf_probe_read_kernel]; \ 66962587Sitojunl0_%=: exit; \ 67062587Sitojun" : 67162587Sitojun : __imm(bpf_map_lookup_elem), 67262587Sitojun __imm(bpf_probe_read_kernel), 67362587Sitojun __imm_addr(map_hash_48b), 67462587Sitojun __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 1), 67562587Sitojun __imm_const(test_val_foo, offsetof(struct test_val, foo)) 67662587Sitojun : __clobber_all); 67762587Sitojun} 67862587Sitojun 67962587SitojunSEC("tracepoint") 68062587Sitojun__description("helper access to map: bounds check using <, good access") 68162587Sitojun__success 68262587Sitojun__naked void bounds_check_using_good_access_1(void) 68362587Sitojun{ 68462587Sitojun asm volatile (" \ 68562587Sitojun r2 = r10; \ 68662587Sitojun r2 += -8; \ 68762587Sitojun r1 = 0; \ 68862587Sitojun *(u64*)(r2 + 0) = r1; \ 68962587Sitojun r1 = %[map_hash_48b] ll; \ 69062587Sitojun call %[bpf_map_lookup_elem]; \ 69162587Sitojun if r0 == 0 goto l0_%=; \ 69262587Sitojun r1 = r0; \ 69362587Sitojun r3 = *(u32*)(r0 + 0); \ 69462587Sitojun if r3 < 32 goto l1_%=; \ 69562587Sitojun r0 = 0; \ 69662587Sitojunl0_%=: exit; \ 69762587Sitojunl1_%=: r1 += r3; \ 69862587Sitojun r0 = 0; \ 69962587Sitojun *(u8*)(r1 + 0) = r0; \ 70062587Sitojun r0 = 0; \ 70162587Sitojun exit; \ 70262587Sitojun" : 70362587Sitojun : __imm(bpf_map_lookup_elem), 70462587Sitojun __imm_addr(map_hash_48b) 70562587Sitojun : __clobber_all); 70662587Sitojun} 70762587Sitojun 70862587SitojunSEC("tracepoint") 70962587Sitojun__description("helper access to map: bounds check using <, bad access") 71062587Sitojun__failure __msg("R1 unbounded memory access") 711__naked void bounds_check_using_bad_access_1(void) 712{ 713 asm volatile (" \ 714 r2 = r10; \ 715 r2 += -8; \ 716 r1 = 0; \ 717 *(u64*)(r2 + 0) = r1; \ 718 r1 = %[map_hash_48b] ll; \ 719 call %[bpf_map_lookup_elem]; \ 720 if r0 == 0 goto l0_%=; \ 721 r1 = r0; \ 722 r3 = *(u32*)(r0 + 0); \ 723 if r3 < 32 goto l1_%=; \ 724 r1 += r3; \ 725l0_%=: r0 = 0; \ 726 *(u8*)(r1 + 0) = r0; \ 727 r0 = 0; \ 728 exit; \ 729l1_%=: r0 = 0; \ 730 exit; \ 731" : 732 : __imm(bpf_map_lookup_elem), 733 __imm_addr(map_hash_48b) 734 : __clobber_all); 735} 736 737SEC("tracepoint") 738__description("helper access to map: bounds check using <=, good access") 739__success 740__naked void bounds_check_using_good_access_2(void) 741{ 742 asm volatile (" \ 743 r2 = r10; \ 744 r2 += -8; \ 745 r1 = 0; \ 746 *(u64*)(r2 + 0) = r1; \ 747 r1 = %[map_hash_48b] ll; \ 748 call %[bpf_map_lookup_elem]; \ 749 if r0 == 0 goto l0_%=; \ 750 r1 = r0; \ 751 r3 = *(u32*)(r0 + 0); \ 752 if r3 <= 32 goto l1_%=; \ 753 r0 = 0; \ 754l0_%=: exit; \ 755l1_%=: r1 += r3; \ 756 r0 = 0; \ 757 *(u8*)(r1 + 0) = r0; \ 758 r0 = 0; \ 759 exit; \ 760" : 761 : __imm(bpf_map_lookup_elem), 762 __imm_addr(map_hash_48b) 763 : __clobber_all); 764} 765 766SEC("tracepoint") 767__description("helper access to map: bounds check using <=, bad access") 768__failure __msg("R1 unbounded memory access") 769__naked void bounds_check_using_bad_access_2(void) 770{ 771 asm volatile (" \ 772 r2 = r10; \ 773 r2 += -8; \ 774 r1 = 0; \ 775 *(u64*)(r2 + 0) = r1; \ 776 r1 = %[map_hash_48b] ll; \ 777 call %[bpf_map_lookup_elem]; \ 778 if r0 == 0 goto l0_%=; \ 779 r1 = r0; \ 780 r3 = *(u32*)(r0 + 0); \ 781 if r3 <= 32 goto l1_%=; \ 782 r1 += r3; \ 783l0_%=: r0 = 0; \ 784 *(u8*)(r1 + 0) = r0; \ 785 r0 = 0; \ 786 exit; \ 787l1_%=: r0 = 0; \ 788 exit; \ 789" : 790 : __imm(bpf_map_lookup_elem), 791 __imm_addr(map_hash_48b) 792 : __clobber_all); 793} 794 795SEC("tracepoint") 796__description("helper access to map: bounds check using s<, good access") 797__success 798__naked void check_using_s_good_access_1(void) 799{ 800 asm volatile (" \ 801 r2 = r10; \ 802 r2 += -8; \ 803 r1 = 0; \ 804 *(u64*)(r2 + 0) = r1; \ 805 r1 = %[map_hash_48b] ll; \ 806 call %[bpf_map_lookup_elem]; \ 807 if r0 == 0 goto l0_%=; \ 808 r1 = r0; \ 809 r3 = *(u32*)(r0 + 0); \ 810 if r3 s< 32 goto l1_%=; \ 811l2_%=: r0 = 0; \ 812l0_%=: exit; \ 813l1_%=: if r3 s< 0 goto l2_%=; \ 814 r1 += r3; \ 815 r0 = 0; \ 816 *(u8*)(r1 + 0) = r0; \ 817 r0 = 0; \ 818 exit; \ 819" : 820 : __imm(bpf_map_lookup_elem), 821 __imm_addr(map_hash_48b) 822 : __clobber_all); 823} 824 825SEC("tracepoint") 826__description("helper access to map: bounds check using s<, good access 2") 827__success 828__naked void using_s_good_access_2_1(void) 829{ 830 asm volatile (" \ 831 r2 = r10; \ 832 r2 += -8; \ 833 r1 = 0; \ 834 *(u64*)(r2 + 0) = r1; \ 835 r1 = %[map_hash_48b] ll; \ 836 call %[bpf_map_lookup_elem]; \ 837 if r0 == 0 goto l0_%=; \ 838 r1 = r0; \ 839 r3 = *(u32*)(r0 + 0); \ 840 if r3 s< 32 goto l1_%=; \ 841l2_%=: r0 = 0; \ 842l0_%=: exit; \ 843l1_%=: if r3 s< -3 goto l2_%=; \ 844 r1 += r3; \ 845 r0 = 0; \ 846 *(u8*)(r1 + 0) = r0; \ 847 r0 = 0; \ 848 exit; \ 849" : 850 : __imm(bpf_map_lookup_elem), 851 __imm_addr(map_hash_48b) 852 : __clobber_all); 853} 854 855SEC("tracepoint") 856__description("helper access to map: bounds check using s<, bad access") 857__failure __msg("R1 min value is negative") 858__naked void check_using_s_bad_access_1(void) 859{ 860 asm volatile (" \ 861 r2 = r10; \ 862 r2 += -8; \ 863 r1 = 0; \ 864 *(u64*)(r2 + 0) = r1; \ 865 r1 = %[map_hash_48b] ll; \ 866 call %[bpf_map_lookup_elem]; \ 867 if r0 == 0 goto l0_%=; \ 868 r1 = r0; \ 869 r3 = *(u64*)(r0 + 0); \ 870 if r3 s< 32 goto l1_%=; \ 871l2_%=: r0 = 0; \ 872l0_%=: exit; \ 873l1_%=: if r3 s< -3 goto l2_%=; \ 874 r1 += r3; \ 875 r0 = 0; \ 876 *(u8*)(r1 + 0) = r0; \ 877 r0 = 0; \ 878 exit; \ 879" : 880 : __imm(bpf_map_lookup_elem), 881 __imm_addr(map_hash_48b) 882 : __clobber_all); 883} 884 885SEC("tracepoint") 886__description("helper access to map: bounds check using s<=, good access") 887__success 888__naked void check_using_s_good_access_2(void) 889{ 890 asm volatile (" \ 891 r2 = r10; \ 892 r2 += -8; \ 893 r1 = 0; \ 894 *(u64*)(r2 + 0) = r1; \ 895 r1 = %[map_hash_48b] ll; \ 896 call %[bpf_map_lookup_elem]; \ 897 if r0 == 0 goto l0_%=; \ 898 r1 = r0; \ 899 r3 = *(u32*)(r0 + 0); \ 900 if r3 s<= 32 goto l1_%=; \ 901l2_%=: r0 = 0; \ 902l0_%=: exit; \ 903l1_%=: if r3 s<= 0 goto l2_%=; \ 904 r1 += r3; \ 905 r0 = 0; \ 906 *(u8*)(r1 + 0) = r0; \ 907 r0 = 0; \ 908 exit; \ 909" : 910 : __imm(bpf_map_lookup_elem), 911 __imm_addr(map_hash_48b) 912 : __clobber_all); 913} 914 915SEC("tracepoint") 916__description("helper access to map: bounds check using s<=, good access 2") 917__success 918__naked void using_s_good_access_2_2(void) 919{ 920 asm volatile (" \ 921 r2 = r10; \ 922 r2 += -8; \ 923 r1 = 0; \ 924 *(u64*)(r2 + 0) = r1; \ 925 r1 = %[map_hash_48b] ll; \ 926 call %[bpf_map_lookup_elem]; \ 927 if r0 == 0 goto l0_%=; \ 928 r1 = r0; \ 929 r3 = *(u32*)(r0 + 0); \ 930 if r3 s<= 32 goto l1_%=; \ 931l2_%=: r0 = 0; \ 932l0_%=: exit; \ 933l1_%=: if r3 s<= -3 goto l2_%=; \ 934 r1 += r3; \ 935 r0 = 0; \ 936 *(u8*)(r1 + 0) = r0; \ 937 r0 = 0; \ 938 exit; \ 939" : 940 : __imm(bpf_map_lookup_elem), 941 __imm_addr(map_hash_48b) 942 : __clobber_all); 943} 944 945SEC("tracepoint") 946__description("helper access to map: bounds check using s<=, bad access") 947__failure __msg("R1 min value is negative") 948__naked void check_using_s_bad_access_2(void) 949{ 950 asm volatile (" \ 951 r2 = r10; \ 952 r2 += -8; \ 953 r1 = 0; \ 954 *(u64*)(r2 + 0) = r1; \ 955 r1 = %[map_hash_48b] ll; \ 956 call %[bpf_map_lookup_elem]; \ 957 if r0 == 0 goto l0_%=; \ 958 r1 = r0; \ 959 r3 = *(u64*)(r0 + 0); \ 960 if r3 s<= 32 goto l1_%=; \ 961l2_%=: r0 = 0; \ 962l0_%=: exit; \ 963l1_%=: if r3 s<= -3 goto l2_%=; \ 964 r1 += r3; \ 965 r0 = 0; \ 966 *(u8*)(r1 + 0) = r0; \ 967 r0 = 0; \ 968 exit; \ 969" : 970 : __imm(bpf_map_lookup_elem), 971 __imm_addr(map_hash_48b) 972 : __clobber_all); 973} 974 975SEC("tracepoint") 976__description("map lookup helper access to map") 977__success 978__naked void lookup_helper_access_to_map(void) 979{ 980 asm volatile (" \ 981 r2 = r10; \ 982 r2 += -8; \ 983 r1 = 0; \ 984 *(u64*)(r2 + 0) = r1; \ 985 r1 = %[map_hash_16b] ll; \ 986 call %[bpf_map_lookup_elem]; \ 987 if r0 == 0 goto l0_%=; \ 988 r2 = r0; \ 989 r1 = %[map_hash_16b] ll; \ 990 call %[bpf_map_lookup_elem]; \ 991l0_%=: exit; \ 992" : 993 : __imm(bpf_map_lookup_elem), 994 __imm_addr(map_hash_16b) 995 : __clobber_all); 996} 997 998SEC("tracepoint") 999__description("map update helper access to map") 1000__success 1001__naked void update_helper_access_to_map(void) 1002{ 1003 asm volatile (" \ 1004 r2 = r10; \ 1005 r2 += -8; \ 1006 r1 = 0; \ 1007 *(u64*)(r2 + 0) = r1; \ 1008 r1 = %[map_hash_16b] ll; \ 1009 call %[bpf_map_lookup_elem]; \ 1010 if r0 == 0 goto l0_%=; \ 1011 r4 = 0; \ 1012 r3 = r0; \ 1013 r2 = r0; \ 1014 r1 = %[map_hash_16b] ll; \ 1015 call %[bpf_map_update_elem]; \ 1016l0_%=: exit; \ 1017" : 1018 : __imm(bpf_map_lookup_elem), 1019 __imm(bpf_map_update_elem), 1020 __imm_addr(map_hash_16b) 1021 : __clobber_all); 1022} 1023 1024SEC("tracepoint") 1025__description("map update helper access to map: wrong size") 1026__failure __msg("invalid access to map value, value_size=8 off=0 size=16") 1027__naked void access_to_map_wrong_size(void) 1028{ 1029 asm volatile (" \ 1030 r2 = r10; \ 1031 r2 += -8; \ 1032 r1 = 0; \ 1033 *(u64*)(r2 + 0) = r1; \ 1034 r1 = %[map_hash_8b] ll; \ 1035 call %[bpf_map_lookup_elem]; \ 1036 if r0 == 0 goto l0_%=; \ 1037 r4 = 0; \ 1038 r3 = r0; \ 1039 r2 = r0; \ 1040 r1 = %[map_hash_16b] ll; \ 1041 call %[bpf_map_update_elem]; \ 1042l0_%=: exit; \ 1043" : 1044 : __imm(bpf_map_lookup_elem), 1045 __imm(bpf_map_update_elem), 1046 __imm_addr(map_hash_16b), 1047 __imm_addr(map_hash_8b) 1048 : __clobber_all); 1049} 1050 1051SEC("tracepoint") 1052__description("map helper access to adjusted map (via const imm)") 1053__success 1054__naked void adjusted_map_via_const_imm(void) 1055{ 1056 asm volatile (" \ 1057 r2 = r10; \ 1058 r2 += -8; \ 1059 r1 = 0; \ 1060 *(u64*)(r2 + 0) = r1; \ 1061 r1 = %[map_hash_16b] ll; \ 1062 call %[bpf_map_lookup_elem]; \ 1063 if r0 == 0 goto l0_%=; \ 1064 r2 = r0; \ 1065 r2 += %[other_val_bar]; \ 1066 r1 = %[map_hash_16b] ll; \ 1067 call %[bpf_map_lookup_elem]; \ 1068l0_%=: exit; \ 1069" : 1070 : __imm(bpf_map_lookup_elem), 1071 __imm_addr(map_hash_16b), 1072 __imm_const(other_val_bar, offsetof(struct other_val, bar)) 1073 : __clobber_all); 1074} 1075 1076SEC("tracepoint") 1077__description("map helper access to adjusted map (via const imm): out-of-bound 1") 1078__failure __msg("invalid access to map value, value_size=16 off=12 size=8") 1079__naked void imm_out_of_bound_1(void) 1080{ 1081 asm volatile (" \ 1082 r2 = r10; \ 1083 r2 += -8; \ 1084 r1 = 0; \ 1085 *(u64*)(r2 + 0) = r1; \ 1086 r1 = %[map_hash_16b] ll; \ 1087 call %[bpf_map_lookup_elem]; \ 1088 if r0 == 0 goto l0_%=; \ 1089 r2 = r0; \ 1090 r2 += %[__imm_0]; \ 1091 r1 = %[map_hash_16b] ll; \ 1092 call %[bpf_map_lookup_elem]; \ 1093l0_%=: exit; \ 1094" : 1095 : __imm(bpf_map_lookup_elem), 1096 __imm_addr(map_hash_16b), 1097 __imm_const(__imm_0, sizeof(struct other_val) - 4) 1098 : __clobber_all); 1099} 1100 1101SEC("tracepoint") 1102__description("map helper access to adjusted map (via const imm): out-of-bound 2") 1103__failure __msg("invalid access to map value, value_size=16 off=-4 size=8") 1104__naked void imm_out_of_bound_2(void) 1105{ 1106 asm volatile (" \ 1107 r2 = r10; \ 1108 r2 += -8; \ 1109 r1 = 0; \ 1110 *(u64*)(r2 + 0) = r1; \ 1111 r1 = %[map_hash_16b] ll; \ 1112 call %[bpf_map_lookup_elem]; \ 1113 if r0 == 0 goto l0_%=; \ 1114 r2 = r0; \ 1115 r2 += -4; \ 1116 r1 = %[map_hash_16b] ll; \ 1117 call %[bpf_map_lookup_elem]; \ 1118l0_%=: exit; \ 1119" : 1120 : __imm(bpf_map_lookup_elem), 1121 __imm_addr(map_hash_16b) 1122 : __clobber_all); 1123} 1124 1125SEC("tracepoint") 1126__description("map helper access to adjusted map (via const reg)") 1127__success 1128__naked void adjusted_map_via_const_reg(void) 1129{ 1130 asm volatile (" \ 1131 r2 = r10; \ 1132 r2 += -8; \ 1133 r1 = 0; \ 1134 *(u64*)(r2 + 0) = r1; \ 1135 r1 = %[map_hash_16b] ll; \ 1136 call %[bpf_map_lookup_elem]; \ 1137 if r0 == 0 goto l0_%=; \ 1138 r2 = r0; \ 1139 r3 = %[other_val_bar]; \ 1140 r2 += r3; \ 1141 r1 = %[map_hash_16b] ll; \ 1142 call %[bpf_map_lookup_elem]; \ 1143l0_%=: exit; \ 1144" : 1145 : __imm(bpf_map_lookup_elem), 1146 __imm_addr(map_hash_16b), 1147 __imm_const(other_val_bar, offsetof(struct other_val, bar)) 1148 : __clobber_all); 1149} 1150 1151SEC("tracepoint") 1152__description("map helper access to adjusted map (via const reg): out-of-bound 1") 1153__failure __msg("invalid access to map value, value_size=16 off=12 size=8") 1154__naked void reg_out_of_bound_1(void) 1155{ 1156 asm volatile (" \ 1157 r2 = r10; \ 1158 r2 += -8; \ 1159 r1 = 0; \ 1160 *(u64*)(r2 + 0) = r1; \ 1161 r1 = %[map_hash_16b] ll; \ 1162 call %[bpf_map_lookup_elem]; \ 1163 if r0 == 0 goto l0_%=; \ 1164 r2 = r0; \ 1165 r3 = %[__imm_0]; \ 1166 r2 += r3; \ 1167 r1 = %[map_hash_16b] ll; \ 1168 call %[bpf_map_lookup_elem]; \ 1169l0_%=: exit; \ 1170" : 1171 : __imm(bpf_map_lookup_elem), 1172 __imm_addr(map_hash_16b), 1173 __imm_const(__imm_0, sizeof(struct other_val) - 4) 1174 : __clobber_all); 1175} 1176 1177SEC("tracepoint") 1178__description("map helper access to adjusted map (via const reg): out-of-bound 2") 1179__failure __msg("invalid access to map value, value_size=16 off=-4 size=8") 1180__naked void reg_out_of_bound_2(void) 1181{ 1182 asm volatile (" \ 1183 r2 = r10; \ 1184 r2 += -8; \ 1185 r1 = 0; \ 1186 *(u64*)(r2 + 0) = r1; \ 1187 r1 = %[map_hash_16b] ll; \ 1188 call %[bpf_map_lookup_elem]; \ 1189 if r0 == 0 goto l0_%=; \ 1190 r2 = r0; \ 1191 r3 = -4; \ 1192 r2 += r3; \ 1193 r1 = %[map_hash_16b] ll; \ 1194 call %[bpf_map_lookup_elem]; \ 1195l0_%=: exit; \ 1196" : 1197 : __imm(bpf_map_lookup_elem), 1198 __imm_addr(map_hash_16b) 1199 : __clobber_all); 1200} 1201 1202SEC("tracepoint") 1203__description("map helper access to adjusted map (via variable)") 1204__success 1205__naked void to_adjusted_map_via_variable(void) 1206{ 1207 asm volatile (" \ 1208 r2 = r10; \ 1209 r2 += -8; \ 1210 r1 = 0; \ 1211 *(u64*)(r2 + 0) = r1; \ 1212 r1 = %[map_hash_16b] ll; \ 1213 call %[bpf_map_lookup_elem]; \ 1214 if r0 == 0 goto l0_%=; \ 1215 r2 = r0; \ 1216 r3 = *(u32*)(r0 + 0); \ 1217 if r3 > %[other_val_bar] goto l0_%=; \ 1218 r2 += r3; \ 1219 r1 = %[map_hash_16b] ll; \ 1220 call %[bpf_map_lookup_elem]; \ 1221l0_%=: exit; \ 1222" : 1223 : __imm(bpf_map_lookup_elem), 1224 __imm_addr(map_hash_16b), 1225 __imm_const(other_val_bar, offsetof(struct other_val, bar)) 1226 : __clobber_all); 1227} 1228 1229SEC("tracepoint") 1230__description("map helper access to adjusted map (via variable): no max check") 1231__failure 1232__msg("R2 unbounded memory access, make sure to bounds check any such access") 1233__naked void via_variable_no_max_check_2(void) 1234{ 1235 asm volatile (" \ 1236 r2 = r10; \ 1237 r2 += -8; \ 1238 r1 = 0; \ 1239 *(u64*)(r2 + 0) = r1; \ 1240 r1 = %[map_hash_16b] ll; \ 1241 call %[bpf_map_lookup_elem]; \ 1242 if r0 == 0 goto l0_%=; \ 1243 r2 = r0; \ 1244 r3 = *(u32*)(r0 + 0); \ 1245 r2 += r3; \ 1246 r1 = %[map_hash_16b] ll; \ 1247 call %[bpf_map_lookup_elem]; \ 1248l0_%=: exit; \ 1249" : 1250 : __imm(bpf_map_lookup_elem), 1251 __imm_addr(map_hash_16b) 1252 : __clobber_all); 1253} 1254 1255SEC("tracepoint") 1256__description("map helper access to adjusted map (via variable): wrong max check") 1257__failure __msg("invalid access to map value, value_size=16 off=9 size=8") 1258__naked void via_variable_wrong_max_check_2(void) 1259{ 1260 asm volatile (" \ 1261 r2 = r10; \ 1262 r2 += -8; \ 1263 r1 = 0; \ 1264 *(u64*)(r2 + 0) = r1; \ 1265 r1 = %[map_hash_16b] ll; \ 1266 call %[bpf_map_lookup_elem]; \ 1267 if r0 == 0 goto l0_%=; \ 1268 r2 = r0; \ 1269 r3 = *(u32*)(r0 + 0); \ 1270 if r3 > %[__imm_0] goto l0_%=; \ 1271 r2 += r3; \ 1272 r1 = %[map_hash_16b] ll; \ 1273 call %[bpf_map_lookup_elem]; \ 1274l0_%=: exit; \ 1275" : 1276 : __imm(bpf_map_lookup_elem), 1277 __imm_addr(map_hash_16b), 1278 __imm_const(__imm_0, offsetof(struct other_val, bar) + 1) 1279 : __clobber_all); 1280} 1281 1282char _license[] SEC("license") = "GPL"; 1283