103391494SEduard Zingerman // SPDX-License-Identifier: GPL-2.0 203391494SEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/value_adj_spill.c */ 303391494SEduard Zingerman 403391494SEduard Zingerman #include <linux/bpf.h> 503391494SEduard Zingerman #include <bpf/bpf_helpers.h> 603391494SEduard Zingerman #include "bpf_misc.h" 703391494SEduard Zingerman 803391494SEduard Zingerman #define MAX_ENTRIES 11 903391494SEduard Zingerman 1003391494SEduard Zingerman struct test_val { 1103391494SEduard Zingerman unsigned int index; 1203391494SEduard Zingerman int foo[MAX_ENTRIES]; 1303391494SEduard Zingerman }; 1403391494SEduard Zingerman 1503391494SEduard Zingerman struct { 1603391494SEduard Zingerman __uint(type, BPF_MAP_TYPE_HASH); 1703391494SEduard Zingerman __uint(max_entries, 1); 1803391494SEduard Zingerman __type(key, long long); 1903391494SEduard Zingerman __type(value, struct test_val); 2003391494SEduard Zingerman } map_hash_48b SEC(".maps"); 2103391494SEduard Zingerman 2203391494SEduard Zingerman SEC("socket") 2303391494SEduard Zingerman __description("map element value is preserved across register spilling") 2403391494SEduard Zingerman __success __failure_unpriv __msg_unpriv("R0 leaks addr") 2503391494SEduard Zingerman __retval(0) is_preserved_across_register_spilling(void)2603391494SEduard Zingerman__naked void is_preserved_across_register_spilling(void) 2703391494SEduard Zingerman { 2803391494SEduard Zingerman asm volatile (" \ 2903391494SEduard Zingerman r2 = r10; \ 3003391494SEduard Zingerman r2 += -8; \ 3103391494SEduard Zingerman r1 = 0; \ 3203391494SEduard Zingerman *(u64*)(r2 + 0) = r1; \ 3303391494SEduard Zingerman r1 = %[map_hash_48b] ll; \ 3403391494SEduard Zingerman call %[bpf_map_lookup_elem]; \ 3503391494SEduard Zingerman if r0 == 0 goto l0_%=; \ 3603391494SEduard Zingerman r1 = 42; \ 3703391494SEduard Zingerman *(u64*)(r0 + 0) = r1; \ 3803391494SEduard Zingerman r1 = r10; \ 3903391494SEduard Zingerman r1 += -184; \ 4003391494SEduard Zingerman *(u64*)(r1 + 0) = r0; \ 4103391494SEduard Zingerman r3 = *(u64*)(r1 + 0); \ 4203391494SEduard Zingerman r1 = 42; \ 4303391494SEduard Zingerman *(u64*)(r3 + 0) = r1; \ 4403391494SEduard Zingerman l0_%=: exit; \ 4503391494SEduard Zingerman " : 4603391494SEduard Zingerman : __imm(bpf_map_lookup_elem), 4703391494SEduard Zingerman __imm_addr(map_hash_48b) 4803391494SEduard Zingerman : __clobber_all); 4903391494SEduard Zingerman } 5003391494SEduard Zingerman 5103391494SEduard Zingerman SEC("socket") 5203391494SEduard Zingerman __description("map element value or null is marked on register spilling") 5303391494SEduard Zingerman __success __failure_unpriv __msg_unpriv("R0 leaks addr") 5403391494SEduard Zingerman __retval(0) is_marked_on_register_spilling(void)5503391494SEduard Zingerman__naked void is_marked_on_register_spilling(void) 5603391494SEduard Zingerman { 5703391494SEduard Zingerman asm volatile (" \ 5803391494SEduard Zingerman r2 = r10; \ 5903391494SEduard Zingerman r2 += -8; \ 6003391494SEduard Zingerman r1 = 0; \ 6103391494SEduard Zingerman *(u64*)(r2 + 0) = r1; \ 6203391494SEduard Zingerman r1 = %[map_hash_48b] ll; \ 6303391494SEduard Zingerman call %[bpf_map_lookup_elem]; \ 6403391494SEduard Zingerman r1 = r10; \ 6503391494SEduard Zingerman r1 += -152; \ 6603391494SEduard Zingerman *(u64*)(r1 + 0) = r0; \ 6703391494SEduard Zingerman if r0 == 0 goto l0_%=; \ 6803391494SEduard Zingerman r3 = *(u64*)(r1 + 0); \ 6903391494SEduard Zingerman r1 = 42; \ 7003391494SEduard Zingerman *(u64*)(r3 + 0) = r1; \ 7103391494SEduard Zingerman l0_%=: exit; \ 7203391494SEduard Zingerman " : 7303391494SEduard Zingerman : __imm(bpf_map_lookup_elem), 7403391494SEduard Zingerman __imm_addr(map_hash_48b) 7503391494SEduard Zingerman : __clobber_all); 7603391494SEduard Zingerman } 7703391494SEduard Zingerman 7803391494SEduard Zingerman char _license[] SEC("license") = "GPL"; 79