]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/progs/verifier_value_or_null.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / progs / verifier_value_or_null.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/value_or_null.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 struct {
23         __uint(type, BPF_MAP_TYPE_HASH);
24         __uint(max_entries, 1);
25         __type(key, long long);
26         __type(value, long long);
27 } map_hash_8b SEC(".maps");
28
29 SEC("tc")
30 __description("multiple registers share map_lookup_elem result")
31 __success __retval(0)
32 __naked void share_map_lookup_elem_result(void)
33 {
34         asm volatile ("                                 \
35         r1 = 10;                                        \
36         *(u64*)(r10 - 8) = r1;                          \
37         r2 = r10;                                       \
38         r2 += -8;                                       \
39         r1 = %[map_hash_8b] ll;                         \
40         call %[bpf_map_lookup_elem];                    \
41         r4 = r0;                                        \
42         if r0 == 0 goto l0_%=;                          \
43         r1 = 0;                                         \
44         *(u64*)(r4 + 0) = r1;                           \
45 l0_%=:  exit;                                           \
46 "       :
47         : __imm(bpf_map_lookup_elem),
48           __imm_addr(map_hash_8b)
49         : __clobber_all);
50 }
51
52 SEC("tc")
53 __description("alu ops on ptr_to_map_value_or_null, 1")
54 __failure __msg("R4 pointer arithmetic on map_value_or_null")
55 __naked void map_value_or_null_1(void)
56 {
57         asm volatile ("                                 \
58         r1 = 10;                                        \
59         *(u64*)(r10 - 8) = r1;                          \
60         r2 = r10;                                       \
61         r2 += -8;                                       \
62         r1 = %[map_hash_8b] ll;                         \
63         call %[bpf_map_lookup_elem];                    \
64         r4 = r0;                                        \
65         r4 += -2;                                       \
66         r4 += 2;                                        \
67         if r0 == 0 goto l0_%=;                          \
68         r1 = 0;                                         \
69         *(u64*)(r4 + 0) = r1;                           \
70 l0_%=:  exit;                                           \
71 "       :
72         : __imm(bpf_map_lookup_elem),
73           __imm_addr(map_hash_8b)
74         : __clobber_all);
75 }
76
77 SEC("tc")
78 __description("alu ops on ptr_to_map_value_or_null, 2")
79 __failure __msg("R4 pointer arithmetic on map_value_or_null")
80 __naked void map_value_or_null_2(void)
81 {
82         asm volatile ("                                 \
83         r1 = 10;                                        \
84         *(u64*)(r10 - 8) = r1;                          \
85         r2 = r10;                                       \
86         r2 += -8;                                       \
87         r1 = %[map_hash_8b] ll;                         \
88         call %[bpf_map_lookup_elem];                    \
89         r4 = r0;                                        \
90         r4 &= -1;                                       \
91         if r0 == 0 goto l0_%=;                          \
92         r1 = 0;                                         \
93         *(u64*)(r4 + 0) = r1;                           \
94 l0_%=:  exit;                                           \
95 "       :
96         : __imm(bpf_map_lookup_elem),
97           __imm_addr(map_hash_8b)
98         : __clobber_all);
99 }
100
101 SEC("tc")
102 __description("alu ops on ptr_to_map_value_or_null, 3")
103 __failure __msg("R4 pointer arithmetic on map_value_or_null")
104 __naked void map_value_or_null_3(void)
105 {
106         asm volatile ("                                 \
107         r1 = 10;                                        \
108         *(u64*)(r10 - 8) = r1;                          \
109         r2 = r10;                                       \
110         r2 += -8;                                       \
111         r1 = %[map_hash_8b] ll;                         \
112         call %[bpf_map_lookup_elem];                    \
113         r4 = r0;                                        \
114         r4 <<= 1;                                       \
115         if r0 == 0 goto l0_%=;                          \
116         r1 = 0;                                         \
117         *(u64*)(r4 + 0) = r1;                           \
118 l0_%=:  exit;                                           \
119 "       :
120         : __imm(bpf_map_lookup_elem),
121           __imm_addr(map_hash_8b)
122         : __clobber_all);
123 }
124
125 SEC("tc")
126 __description("invalid memory access with multiple map_lookup_elem calls")
127 __failure __msg("R4 !read_ok")
128 __naked void multiple_map_lookup_elem_calls(void)
129 {
130         asm volatile ("                                 \
131         r1 = 10;                                        \
132         *(u64*)(r10 - 8) = r1;                          \
133         r2 = r10;                                       \
134         r2 += -8;                                       \
135         r1 = %[map_hash_8b] ll;                         \
136         r8 = r1;                                        \
137         r7 = r2;                                        \
138         call %[bpf_map_lookup_elem];                    \
139         r4 = r0;                                        \
140         r1 = r8;                                        \
141         r2 = r7;                                        \
142         call %[bpf_map_lookup_elem];                    \
143         if r0 == 0 goto l0_%=;                          \
144         r1 = 0;                                         \
145         *(u64*)(r4 + 0) = r1;                           \
146 l0_%=:  exit;                                           \
147 "       :
148         : __imm(bpf_map_lookup_elem),
149           __imm_addr(map_hash_8b)
150         : __clobber_all);
151 }
152
153 SEC("tc")
154 __description("valid indirect map_lookup_elem access with 2nd lookup in branch")
155 __success __retval(0)
156 __naked void with_2nd_lookup_in_branch(void)
157 {
158         asm volatile ("                                 \
159         r1 = 10;                                        \
160         *(u64*)(r10 - 8) = r1;                          \
161         r2 = r10;                                       \
162         r2 += -8;                                       \
163         r1 = %[map_hash_8b] ll;                         \
164         r8 = r1;                                        \
165         r7 = r2;                                        \
166         call %[bpf_map_lookup_elem];                    \
167         r2 = 10;                                        \
168         if r2 != 0 goto l0_%=;                          \
169         r1 = r8;                                        \
170         r2 = r7;                                        \
171         call %[bpf_map_lookup_elem];                    \
172 l0_%=:  r4 = r0;                                        \
173         if r0 == 0 goto l1_%=;                          \
174         r1 = 0;                                         \
175         *(u64*)(r4 + 0) = r1;                           \
176 l1_%=:  exit;                                           \
177 "       :
178         : __imm(bpf_map_lookup_elem),
179           __imm_addr(map_hash_8b)
180         : __clobber_all);
181 }
182
183 SEC("socket")
184 __description("invalid map access from else condition")
185 __failure __msg("R0 unbounded memory access")
186 __failure_unpriv __msg_unpriv("R0 leaks addr")
187 __flag(BPF_F_ANY_ALIGNMENT)
188 __naked void map_access_from_else_condition(void)
189 {
190         asm volatile ("                                 \
191         r1 = 0;                                         \
192         *(u64*)(r10 - 8) = r1;                          \
193         r2 = r10;                                       \
194         r2 += -8;                                       \
195         r1 = %[map_hash_48b] ll;                        \
196         call %[bpf_map_lookup_elem];                    \
197         if r0 == 0 goto l0_%=;                          \
198         r1 = *(u32*)(r0 + 0);                           \
199         if r1 >= %[__imm_0] goto l1_%=;                 \
200         r1 += 1;                                        \
201 l1_%=:  r1 <<= 2;                                       \
202         r0 += r1;                                       \
203         r1 = %[test_val_foo];                           \
204         *(u64*)(r0 + 0) = r1;                           \
205 l0_%=:  exit;                                           \
206 "       :
207         : __imm(bpf_map_lookup_elem),
208           __imm_addr(map_hash_48b),
209           __imm_const(__imm_0, MAX_ENTRIES-1),
210           __imm_const(test_val_foo, offsetof(struct test_val, foo))
211         : __clobber_all);
212 }
213
214 SEC("tc")
215 __description("map lookup and null branch prediction")
216 __success __retval(0)
217 __naked void lookup_and_null_branch_prediction(void)
218 {
219         asm volatile ("                                 \
220         r1 = 10;                                        \
221         *(u64*)(r10 - 8) = r1;                          \
222         r2 = r10;                                       \
223         r2 += -8;                                       \
224         r1 = %[map_hash_8b] ll;                         \
225         call %[bpf_map_lookup_elem];                    \
226         r6 = r0;                                        \
227         if r6 == 0 goto l0_%=;                          \
228         if r6 != 0 goto l0_%=;                          \
229         r10 += 10;                                      \
230 l0_%=:  exit;                                           \
231 "       :
232         : __imm(bpf_map_lookup_elem),
233           __imm_addr(map_hash_8b)
234         : __clobber_all);
235 }
236
237 SEC("cgroup/skb")
238 __description("MAP_VALUE_OR_NULL check_ids() in regsafe()")
239 __failure __msg("R8 invalid mem access 'map_value_or_null'")
240 __failure_unpriv __msg_unpriv("")
241 __flag(BPF_F_TEST_STATE_FREQ)
242 __naked void null_check_ids_in_regsafe(void)
243 {
244         asm volatile ("                                 \
245         r1 = 0;                                         \
246         *(u64*)(r10 - 8) = r1;                          \
247         /* r9 = map_lookup_elem(...) */                 \
248         r2 = r10;                                       \
249         r2 += -8;                                       \
250         r1 = %[map_hash_8b] ll;                         \
251         call %[bpf_map_lookup_elem];                    \
252         r9 = r0;                                        \
253         /* r8 = map_lookup_elem(...) */                 \
254         r2 = r10;                                       \
255         r2 += -8;                                       \
256         r1 = %[map_hash_8b] ll;                         \
257         call %[bpf_map_lookup_elem];                    \
258         r8 = r0;                                        \
259         /* r7 = ktime_get_ns() */                       \
260         call %[bpf_ktime_get_ns];                       \
261         r7 = r0;                                        \
262         /* r6 = ktime_get_ns() */                       \
263         call %[bpf_ktime_get_ns];                       \
264         r6 = r0;                                        \
265         /* if r6 > r7 goto +1    ; no new information about the state is derived from\
266          *                       ; this check, thus produced verifier states differ\
267          *                       ; only in 'insn_idx'   \
268          * r9 = r8               ; optionally share ID between r9 and r8\
269          */                                             \
270         if r6 > r7 goto l0_%=;                          \
271         r9 = r8;                                        \
272 l0_%=:  /* if r9 == 0 goto <exit> */                    \
273         if r9 == 0 goto l1_%=;                          \
274         /* read map value via r8, this is not always    \
275          * safe because r8 might be not equal to r9.    \
276          */                                             \
277         r0 = *(u64*)(r8 + 0);                           \
278 l1_%=:  /* exit 0 */                                    \
279         r0 = 0;                                         \
280         exit;                                           \
281 "       :
282         : __imm(bpf_ktime_get_ns),
283           __imm(bpf_map_lookup_elem),
284           __imm_addr(map_hash_8b)
285         : __clobber_all);
286 }
287
288 char _license[] SEC("license") = "GPL";
This page took 0.045909 seconds and 4 git commands to generate.