selftests/bpf: Fix erroneous bitmask operation
[platform/kernel/linux-rpi.git] / tools / testing / selftests / bpf / progs / verifier_value.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/value.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
10 struct test_val {
11         unsigned int index;
12         int foo[MAX_ENTRIES];
13 };
14
15 struct {
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
22 SEC("socket")
23 __description("map element value store of cleared call register")
24 __failure __msg("R1 !read_ok")
25 __failure_unpriv __msg_unpriv("R1 !read_ok")
26 __naked void store_of_cleared_call_register(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         *(u64*)(r0 + 0) = r1;                           \
37 l0_%=:  exit;                                           \
38 "       :
39         : __imm(bpf_map_lookup_elem),
40           __imm_addr(map_hash_48b)
41         : __clobber_all);
42 }
43
44 SEC("socket")
45 __description("map element value with unaligned store")
46 __success __failure_unpriv __msg_unpriv("R0 leaks addr")
47 __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
48 __naked void element_value_with_unaligned_store(void)
49 {
50         asm volatile ("                                 \
51         r2 = r10;                                       \
52         r2 += -8;                                       \
53         r1 = 0;                                         \
54         *(u64*)(r2 + 0) = r1;                           \
55         r1 = %[map_hash_48b] ll;                        \
56         call %[bpf_map_lookup_elem];                    \
57         if r0 == 0 goto l0_%=;                          \
58         r0 += 3;                                        \
59         r1 = 42;                                        \
60         *(u64*)(r0 + 0) = r1;                           \
61         r1 = 43;                                        \
62         *(u64*)(r0 + 2) = r1;                           \
63         r1 = 44;                                        \
64         *(u64*)(r0 - 2) = r1;                           \
65         r8 = r0;                                        \
66         r1 = 32;                                        \
67         *(u64*)(r8 + 0) = r1;                           \
68         r1 = 33;                                        \
69         *(u64*)(r8 + 2) = r1;                           \
70         r1 = 34;                                        \
71         *(u64*)(r8 - 2) = r1;                           \
72         r8 += 5;                                        \
73         r1 = 22;                                        \
74         *(u64*)(r8 + 0) = r1;                           \
75         r1 = 23;                                        \
76         *(u64*)(r8 + 4) = r1;                           \
77         r1 = 24;                                        \
78         *(u64*)(r8 - 7) = r1;                           \
79         r7 = r8;                                        \
80         r7 += 3;                                        \
81         r1 = 22;                                        \
82         *(u64*)(r7 + 0) = r1;                           \
83         r1 = 23;                                        \
84         *(u64*)(r7 + 4) = r1;                           \
85         r1 = 24;                                        \
86         *(u64*)(r7 - 4) = r1;                           \
87 l0_%=:  exit;                                           \
88 "       :
89         : __imm(bpf_map_lookup_elem),
90           __imm_addr(map_hash_48b)
91         : __clobber_all);
92 }
93
94 SEC("socket")
95 __description("map element value with unaligned load")
96 __success __failure_unpriv __msg_unpriv("R0 leaks addr")
97 __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
98 __naked void element_value_with_unaligned_load(void)
99 {
100         asm volatile ("                                 \
101         r2 = r10;                                       \
102         r2 += -8;                                       \
103         r1 = 0;                                         \
104         *(u64*)(r2 + 0) = r1;                           \
105         r1 = %[map_hash_48b] ll;                        \
106         call %[bpf_map_lookup_elem];                    \
107         if r0 == 0 goto l0_%=;                          \
108         r1 = *(u32*)(r0 + 0);                           \
109         if r1 >= %[max_entries] goto l0_%=;             \
110         r0 += 3;                                        \
111         r7 = *(u64*)(r0 + 0);                           \
112         r7 = *(u64*)(r0 + 2);                           \
113         r8 = r0;                                        \
114         r7 = *(u64*)(r8 + 0);                           \
115         r7 = *(u64*)(r8 + 2);                           \
116         r0 += 5;                                        \
117         r7 = *(u64*)(r0 + 0);                           \
118         r7 = *(u64*)(r0 + 4);                           \
119 l0_%=:  exit;                                           \
120 "       :
121         : __imm(bpf_map_lookup_elem),
122           __imm_addr(map_hash_48b),
123           __imm_const(max_entries, MAX_ENTRIES)
124         : __clobber_all);
125 }
126
127 SEC("socket")
128 __description("map element value is preserved across register spilling")
129 __success __failure_unpriv __msg_unpriv("R0 leaks addr")
130 __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
131 __naked void is_preserved_across_register_spilling(void)
132 {
133         asm volatile ("                                 \
134         r2 = r10;                                       \
135         r2 += -8;                                       \
136         r1 = 0;                                         \
137         *(u64*)(r2 + 0) = r1;                           \
138         r1 = %[map_hash_48b] ll;                        \
139         call %[bpf_map_lookup_elem];                    \
140         if r0 == 0 goto l0_%=;                          \
141         r0 += %[test_val_foo];                          \
142         r1 = 42;                                        \
143         *(u64*)(r0 + 0) = r1;                           \
144         r1 = r10;                                       \
145         r1 += -184;                                     \
146         *(u64*)(r1 + 0) = r0;                           \
147         r3 = *(u64*)(r1 + 0);                           \
148         r1 = 42;                                        \
149         *(u64*)(r3 + 0) = r1;                           \
150 l0_%=:  exit;                                           \
151 "       :
152         : __imm(bpf_map_lookup_elem),
153           __imm_addr(map_hash_48b),
154           __imm_const(test_val_foo, offsetof(struct test_val, foo))
155         : __clobber_all);
156 }
157
158 char _license[] SEC("license") = "GPL";