1// SPDX-License-Identifier: GPL-2.0
2/* Converted from tools/testing/selftests/bpf/verifier/value_adj_spill.c */
3
4#include <linux/bpf.h>
5#include <bpf/bpf_helpers.h>
6#include "bpf_misc.h"
7
8#define MAX_ENTRIES 11
9
10struct test_val {
11 unsigned int index;
12 int foo[MAX_ENTRIES];
13};
14
15struct {
16 __uint(type, BPF_MAP_TYPE_HASH);
17 __uint(max_entries, 1);
18 __type(key, long long);
19 __type(value, struct test_val);
20} map_hash_48b SEC(".maps");
21
22SEC("socket")
23__description("map element value is preserved across register spilling")
24__success __failure_unpriv __msg_unpriv("R0 leaks addr")
25__retval(0)
26__naked void is_preserved_across_register_spilling(void)
27{
28 asm volatile (" \
29 r2 = r10; \
30 r2 += -8; \
31 r1 = 0; \
32 *(u64*)(r2 + 0) = r1; \
33 r1 = %[map_hash_48b] ll; \
34 call %[bpf_map_lookup_elem]; \
35 if r0 == 0 goto l0_%=; \
36 r1 = 42; \
37 *(u64*)(r0 + 0) = r1; \
38 r1 = r10; \
39 r1 += -184; \
40 *(u64*)(r1 + 0) = r0; \
41 r3 = *(u64*)(r1 + 0); \
42 r1 = 42; \
43 *(u64*)(r3 + 0) = r1; \
44l0_%=: exit; \
45" :
46 : __imm(bpf_map_lookup_elem),
47 __imm_addr(map_hash_48b)
48 : __clobber_all);
49}
50
51SEC("socket")
52__description("map element value or null is marked on register spilling")
53__success __failure_unpriv __msg_unpriv("R0 leaks addr")
54__retval(0)
55__naked void is_marked_on_register_spilling(void)
56{
57 asm volatile (" \
58 r2 = r10; \
59 r2 += -8; \
60 r1 = 0; \
61 *(u64*)(r2 + 0) = r1; \
62 r1 = %[map_hash_48b] ll; \
63 call %[bpf_map_lookup_elem]; \
64 r1 = r10; \
65 r1 += -152; \
66 *(u64*)(r1 + 0) = r0; \
67 if r0 == 0 goto l0_%=; \
68 r3 = *(u64*)(r1 + 0); \
69 r1 = 42; \
70 *(u64*)(r3 + 0) = r1; \
71l0_%=: exit; \
72" :
73 : __imm(bpf_map_lookup_elem),
74 __imm_addr(map_hash_48b)
75 : __clobber_all);
76}
77
78char _license[] SEC("license") = "GPL";
79

source code of linux/tools/testing/selftests/bpf/progs/verifier_value_adj_spill.c