1*ecc42482SEduard Zingerman // SPDX-License-Identifier: GPL-2.0
2*ecc42482SEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/helper_value_access.c */
3*ecc42482SEduard Zingerman
4*ecc42482SEduard Zingerman #include <linux/bpf.h>
5*ecc42482SEduard Zingerman #include <bpf/bpf_helpers.h>
6*ecc42482SEduard Zingerman #include "bpf_misc.h"
7*ecc42482SEduard Zingerman
8*ecc42482SEduard Zingerman struct other_val {
9*ecc42482SEduard Zingerman long long foo;
10*ecc42482SEduard Zingerman long long bar;
11*ecc42482SEduard Zingerman };
12*ecc42482SEduard Zingerman
13*ecc42482SEduard Zingerman struct {
14*ecc42482SEduard Zingerman __uint(type, BPF_MAP_TYPE_HASH);
15*ecc42482SEduard Zingerman __uint(max_entries, 1);
16*ecc42482SEduard Zingerman __type(key, long long);
17*ecc42482SEduard Zingerman __type(value, struct other_val);
18*ecc42482SEduard Zingerman } map_hash_16b SEC(".maps");
19*ecc42482SEduard Zingerman
20*ecc42482SEduard Zingerman #define MAX_ENTRIES 11
21*ecc42482SEduard Zingerman
22*ecc42482SEduard Zingerman struct test_val {
23*ecc42482SEduard Zingerman unsigned int index;
24*ecc42482SEduard Zingerman int foo[MAX_ENTRIES];
25*ecc42482SEduard Zingerman };
26*ecc42482SEduard Zingerman
27*ecc42482SEduard Zingerman struct {
28*ecc42482SEduard Zingerman __uint(type, BPF_MAP_TYPE_HASH);
29*ecc42482SEduard Zingerman __uint(max_entries, 1);
30*ecc42482SEduard Zingerman __type(key, long long);
31*ecc42482SEduard Zingerman __type(value, struct test_val);
32*ecc42482SEduard Zingerman } map_hash_48b SEC(".maps");
33*ecc42482SEduard Zingerman
34*ecc42482SEduard Zingerman struct {
35*ecc42482SEduard Zingerman __uint(type, BPF_MAP_TYPE_HASH);
36*ecc42482SEduard Zingerman __uint(max_entries, 1);
37*ecc42482SEduard Zingerman __type(key, long long);
38*ecc42482SEduard Zingerman __type(value, long long);
39*ecc42482SEduard Zingerman } map_hash_8b SEC(".maps");
40*ecc42482SEduard Zingerman
41*ecc42482SEduard Zingerman SEC("tracepoint")
42*ecc42482SEduard Zingerman __description("helper access to map: full range")
43*ecc42482SEduard Zingerman __success
access_to_map_full_range(void)44*ecc42482SEduard Zingerman __naked void access_to_map_full_range(void)
45*ecc42482SEduard Zingerman {
46*ecc42482SEduard Zingerman asm volatile (" \
47*ecc42482SEduard Zingerman r2 = r10; \
48*ecc42482SEduard Zingerman r2 += -8; \
49*ecc42482SEduard Zingerman r1 = 0; \
50*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
51*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
52*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
53*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
54*ecc42482SEduard Zingerman r1 = r0; \
55*ecc42482SEduard Zingerman r2 = %[sizeof_test_val]; \
56*ecc42482SEduard Zingerman r3 = 0; \
57*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
58*ecc42482SEduard Zingerman l0_%=: exit; \
59*ecc42482SEduard Zingerman " :
60*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
61*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
62*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
63*ecc42482SEduard Zingerman __imm_const(sizeof_test_val, sizeof(struct test_val))
64*ecc42482SEduard Zingerman : __clobber_all);
65*ecc42482SEduard Zingerman }
66*ecc42482SEduard Zingerman
67*ecc42482SEduard Zingerman SEC("tracepoint")
68*ecc42482SEduard Zingerman __description("helper access to map: partial range")
69*ecc42482SEduard Zingerman __success
access_to_map_partial_range(void)70*ecc42482SEduard Zingerman __naked void access_to_map_partial_range(void)
71*ecc42482SEduard Zingerman {
72*ecc42482SEduard Zingerman asm volatile (" \
73*ecc42482SEduard Zingerman r2 = r10; \
74*ecc42482SEduard Zingerman r2 += -8; \
75*ecc42482SEduard Zingerman r1 = 0; \
76*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
77*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
78*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
79*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
80*ecc42482SEduard Zingerman r1 = r0; \
81*ecc42482SEduard Zingerman r2 = 8; \
82*ecc42482SEduard Zingerman r3 = 0; \
83*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
84*ecc42482SEduard Zingerman l0_%=: exit; \
85*ecc42482SEduard Zingerman " :
86*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
87*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
88*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
89*ecc42482SEduard Zingerman : __clobber_all);
90*ecc42482SEduard Zingerman }
91*ecc42482SEduard Zingerman
92*ecc42482SEduard Zingerman SEC("tracepoint")
93*ecc42482SEduard Zingerman __description("helper access to map: empty range")
94*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=48 off=0 size=0")
access_to_map_empty_range(void)95*ecc42482SEduard Zingerman __naked void access_to_map_empty_range(void)
96*ecc42482SEduard Zingerman {
97*ecc42482SEduard Zingerman asm volatile (" \
98*ecc42482SEduard Zingerman r2 = r10; \
99*ecc42482SEduard Zingerman r2 += -8; \
100*ecc42482SEduard Zingerman r1 = 0; \
101*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
102*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
103*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
104*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
105*ecc42482SEduard Zingerman r1 = r0; \
106*ecc42482SEduard Zingerman r2 = 0; \
107*ecc42482SEduard Zingerman call %[bpf_trace_printk]; \
108*ecc42482SEduard Zingerman l0_%=: exit; \
109*ecc42482SEduard Zingerman " :
110*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
111*ecc42482SEduard Zingerman __imm(bpf_trace_printk),
112*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
113*ecc42482SEduard Zingerman : __clobber_all);
114*ecc42482SEduard Zingerman }
115*ecc42482SEduard Zingerman
116*ecc42482SEduard Zingerman SEC("tracepoint")
117*ecc42482SEduard Zingerman __description("helper access to map: out-of-bound range")
118*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=48 off=0 size=56")
map_out_of_bound_range(void)119*ecc42482SEduard Zingerman __naked void map_out_of_bound_range(void)
120*ecc42482SEduard Zingerman {
121*ecc42482SEduard Zingerman asm volatile (" \
122*ecc42482SEduard Zingerman r2 = r10; \
123*ecc42482SEduard Zingerman r2 += -8; \
124*ecc42482SEduard Zingerman r1 = 0; \
125*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
126*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
127*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
128*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
129*ecc42482SEduard Zingerman r1 = r0; \
130*ecc42482SEduard Zingerman r2 = %[__imm_0]; \
131*ecc42482SEduard Zingerman r3 = 0; \
132*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
133*ecc42482SEduard Zingerman l0_%=: exit; \
134*ecc42482SEduard Zingerman " :
135*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
136*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
137*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
138*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct test_val) + 8)
139*ecc42482SEduard Zingerman : __clobber_all);
140*ecc42482SEduard Zingerman }
141*ecc42482SEduard Zingerman
142*ecc42482SEduard Zingerman SEC("tracepoint")
143*ecc42482SEduard Zingerman __description("helper access to map: negative range")
144*ecc42482SEduard Zingerman __failure __msg("R2 min value is negative")
access_to_map_negative_range(void)145*ecc42482SEduard Zingerman __naked void access_to_map_negative_range(void)
146*ecc42482SEduard Zingerman {
147*ecc42482SEduard Zingerman asm volatile (" \
148*ecc42482SEduard Zingerman r2 = r10; \
149*ecc42482SEduard Zingerman r2 += -8; \
150*ecc42482SEduard Zingerman r1 = 0; \
151*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
152*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
153*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
154*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
155*ecc42482SEduard Zingerman r1 = r0; \
156*ecc42482SEduard Zingerman r2 = -8; \
157*ecc42482SEduard Zingerman r3 = 0; \
158*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
159*ecc42482SEduard Zingerman l0_%=: exit; \
160*ecc42482SEduard Zingerman " :
161*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
162*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
163*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
164*ecc42482SEduard Zingerman : __clobber_all);
165*ecc42482SEduard Zingerman }
166*ecc42482SEduard Zingerman
167*ecc42482SEduard Zingerman SEC("tracepoint")
168*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const imm): full range")
169*ecc42482SEduard Zingerman __success
via_const_imm_full_range(void)170*ecc42482SEduard Zingerman __naked void via_const_imm_full_range(void)
171*ecc42482SEduard Zingerman {
172*ecc42482SEduard Zingerman asm volatile (" \
173*ecc42482SEduard Zingerman r2 = r10; \
174*ecc42482SEduard Zingerman r2 += -8; \
175*ecc42482SEduard Zingerman r1 = 0; \
176*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
177*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
178*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
179*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
180*ecc42482SEduard Zingerman r1 = r0; \
181*ecc42482SEduard Zingerman r1 += %[test_val_foo]; \
182*ecc42482SEduard Zingerman r2 = %[__imm_0]; \
183*ecc42482SEduard Zingerman r3 = 0; \
184*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
185*ecc42482SEduard Zingerman l0_%=: exit; \
186*ecc42482SEduard Zingerman " :
187*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
188*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
189*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
190*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)),
191*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
192*ecc42482SEduard Zingerman : __clobber_all);
193*ecc42482SEduard Zingerman }
194*ecc42482SEduard Zingerman
195*ecc42482SEduard Zingerman SEC("tracepoint")
196*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const imm): partial range")
197*ecc42482SEduard Zingerman __success
via_const_imm_partial_range(void)198*ecc42482SEduard Zingerman __naked void via_const_imm_partial_range(void)
199*ecc42482SEduard Zingerman {
200*ecc42482SEduard Zingerman asm volatile (" \
201*ecc42482SEduard Zingerman r2 = r10; \
202*ecc42482SEduard Zingerman r2 += -8; \
203*ecc42482SEduard Zingerman r1 = 0; \
204*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
205*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
206*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
207*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
208*ecc42482SEduard Zingerman r1 = r0; \
209*ecc42482SEduard Zingerman r1 += %[test_val_foo]; \
210*ecc42482SEduard Zingerman r2 = 8; \
211*ecc42482SEduard Zingerman r3 = 0; \
212*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
213*ecc42482SEduard Zingerman l0_%=: exit; \
214*ecc42482SEduard Zingerman " :
215*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
216*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
217*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
218*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
219*ecc42482SEduard Zingerman : __clobber_all);
220*ecc42482SEduard Zingerman }
221*ecc42482SEduard Zingerman
222*ecc42482SEduard Zingerman SEC("tracepoint")
223*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const imm): empty range")
224*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=48 off=4 size=0")
via_const_imm_empty_range(void)225*ecc42482SEduard Zingerman __naked void via_const_imm_empty_range(void)
226*ecc42482SEduard Zingerman {
227*ecc42482SEduard Zingerman asm volatile (" \
228*ecc42482SEduard Zingerman r2 = r10; \
229*ecc42482SEduard Zingerman r2 += -8; \
230*ecc42482SEduard Zingerman r1 = 0; \
231*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
232*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
233*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
234*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
235*ecc42482SEduard Zingerman r1 = r0; \
236*ecc42482SEduard Zingerman r1 += %[test_val_foo]; \
237*ecc42482SEduard Zingerman r2 = 0; \
238*ecc42482SEduard Zingerman call %[bpf_trace_printk]; \
239*ecc42482SEduard Zingerman l0_%=: exit; \
240*ecc42482SEduard Zingerman " :
241*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
242*ecc42482SEduard Zingerman __imm(bpf_trace_printk),
243*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
244*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
245*ecc42482SEduard Zingerman : __clobber_all);
246*ecc42482SEduard Zingerman }
247*ecc42482SEduard Zingerman
248*ecc42482SEduard Zingerman SEC("tracepoint")
249*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const imm): out-of-bound range")
250*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=48 off=4 size=52")
imm_out_of_bound_range(void)251*ecc42482SEduard Zingerman __naked void imm_out_of_bound_range(void)
252*ecc42482SEduard Zingerman {
253*ecc42482SEduard Zingerman asm volatile (" \
254*ecc42482SEduard Zingerman r2 = r10; \
255*ecc42482SEduard Zingerman r2 += -8; \
256*ecc42482SEduard Zingerman r1 = 0; \
257*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
258*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
259*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
260*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
261*ecc42482SEduard Zingerman r1 = r0; \
262*ecc42482SEduard Zingerman r1 += %[test_val_foo]; \
263*ecc42482SEduard Zingerman r2 = %[__imm_0]; \
264*ecc42482SEduard Zingerman r3 = 0; \
265*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
266*ecc42482SEduard Zingerman l0_%=: exit; \
267*ecc42482SEduard Zingerman " :
268*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
269*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
270*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
271*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 8),
272*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
273*ecc42482SEduard Zingerman : __clobber_all);
274*ecc42482SEduard Zingerman }
275*ecc42482SEduard Zingerman
276*ecc42482SEduard Zingerman SEC("tracepoint")
277*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const imm): negative range (> adjustment)")
278*ecc42482SEduard Zingerman __failure __msg("R2 min value is negative")
const_imm_negative_range_adjustment_1(void)279*ecc42482SEduard Zingerman __naked void const_imm_negative_range_adjustment_1(void)
280*ecc42482SEduard Zingerman {
281*ecc42482SEduard Zingerman asm volatile (" \
282*ecc42482SEduard Zingerman r2 = r10; \
283*ecc42482SEduard Zingerman r2 += -8; \
284*ecc42482SEduard Zingerman r1 = 0; \
285*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
286*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
287*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
288*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
289*ecc42482SEduard Zingerman r1 = r0; \
290*ecc42482SEduard Zingerman r1 += %[test_val_foo]; \
291*ecc42482SEduard Zingerman r2 = -8; \
292*ecc42482SEduard Zingerman r3 = 0; \
293*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
294*ecc42482SEduard Zingerman l0_%=: exit; \
295*ecc42482SEduard Zingerman " :
296*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
297*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
298*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
299*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
300*ecc42482SEduard Zingerman : __clobber_all);
301*ecc42482SEduard Zingerman }
302*ecc42482SEduard Zingerman
303*ecc42482SEduard Zingerman SEC("tracepoint")
304*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const imm): negative range (< adjustment)")
305*ecc42482SEduard Zingerman __failure __msg("R2 min value is negative")
const_imm_negative_range_adjustment_2(void)306*ecc42482SEduard Zingerman __naked void const_imm_negative_range_adjustment_2(void)
307*ecc42482SEduard Zingerman {
308*ecc42482SEduard Zingerman asm volatile (" \
309*ecc42482SEduard Zingerman r2 = r10; \
310*ecc42482SEduard Zingerman r2 += -8; \
311*ecc42482SEduard Zingerman r1 = 0; \
312*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
313*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
314*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
315*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
316*ecc42482SEduard Zingerman r1 = r0; \
317*ecc42482SEduard Zingerman r1 += %[test_val_foo]; \
318*ecc42482SEduard Zingerman r2 = -1; \
319*ecc42482SEduard Zingerman r3 = 0; \
320*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
321*ecc42482SEduard Zingerman l0_%=: exit; \
322*ecc42482SEduard Zingerman " :
323*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
324*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
325*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
326*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
327*ecc42482SEduard Zingerman : __clobber_all);
328*ecc42482SEduard Zingerman }
329*ecc42482SEduard Zingerman
330*ecc42482SEduard Zingerman SEC("tracepoint")
331*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const reg): full range")
332*ecc42482SEduard Zingerman __success
via_const_reg_full_range(void)333*ecc42482SEduard Zingerman __naked void via_const_reg_full_range(void)
334*ecc42482SEduard Zingerman {
335*ecc42482SEduard Zingerman asm volatile (" \
336*ecc42482SEduard Zingerman r2 = r10; \
337*ecc42482SEduard Zingerman r2 += -8; \
338*ecc42482SEduard Zingerman r1 = 0; \
339*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
340*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
341*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
342*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
343*ecc42482SEduard Zingerman r1 = r0; \
344*ecc42482SEduard Zingerman r3 = %[test_val_foo]; \
345*ecc42482SEduard Zingerman r1 += r3; \
346*ecc42482SEduard Zingerman r2 = %[__imm_0]; \
347*ecc42482SEduard Zingerman r3 = 0; \
348*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
349*ecc42482SEduard Zingerman l0_%=: exit; \
350*ecc42482SEduard Zingerman " :
351*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
352*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
353*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
354*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)),
355*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
356*ecc42482SEduard Zingerman : __clobber_all);
357*ecc42482SEduard Zingerman }
358*ecc42482SEduard Zingerman
359*ecc42482SEduard Zingerman SEC("tracepoint")
360*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const reg): partial range")
361*ecc42482SEduard Zingerman __success
via_const_reg_partial_range(void)362*ecc42482SEduard Zingerman __naked void via_const_reg_partial_range(void)
363*ecc42482SEduard Zingerman {
364*ecc42482SEduard Zingerman asm volatile (" \
365*ecc42482SEduard Zingerman r2 = r10; \
366*ecc42482SEduard Zingerman r2 += -8; \
367*ecc42482SEduard Zingerman r1 = 0; \
368*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
369*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
370*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
371*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
372*ecc42482SEduard Zingerman r1 = r0; \
373*ecc42482SEduard Zingerman r3 = %[test_val_foo]; \
374*ecc42482SEduard Zingerman r1 += r3; \
375*ecc42482SEduard Zingerman r2 = 8; \
376*ecc42482SEduard Zingerman r3 = 0; \
377*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
378*ecc42482SEduard Zingerman l0_%=: exit; \
379*ecc42482SEduard Zingerman " :
380*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
381*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
382*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
383*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
384*ecc42482SEduard Zingerman : __clobber_all);
385*ecc42482SEduard Zingerman }
386*ecc42482SEduard Zingerman
387*ecc42482SEduard Zingerman SEC("tracepoint")
388*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const reg): empty range")
389*ecc42482SEduard Zingerman __failure __msg("R1 min value is outside of the allowed memory range")
via_const_reg_empty_range(void)390*ecc42482SEduard Zingerman __naked void via_const_reg_empty_range(void)
391*ecc42482SEduard Zingerman {
392*ecc42482SEduard Zingerman asm volatile (" \
393*ecc42482SEduard Zingerman r2 = r10; \
394*ecc42482SEduard Zingerman r2 += -8; \
395*ecc42482SEduard Zingerman r1 = 0; \
396*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
397*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
398*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
399*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
400*ecc42482SEduard Zingerman r1 = r0; \
401*ecc42482SEduard Zingerman r3 = 0; \
402*ecc42482SEduard Zingerman r1 += r3; \
403*ecc42482SEduard Zingerman r2 = 0; \
404*ecc42482SEduard Zingerman call %[bpf_trace_printk]; \
405*ecc42482SEduard Zingerman l0_%=: exit; \
406*ecc42482SEduard Zingerman " :
407*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
408*ecc42482SEduard Zingerman __imm(bpf_trace_printk),
409*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
410*ecc42482SEduard Zingerman : __clobber_all);
411*ecc42482SEduard Zingerman }
412*ecc42482SEduard Zingerman
413*ecc42482SEduard Zingerman SEC("tracepoint")
414*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const reg): out-of-bound range")
415*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=48 off=4 size=52")
reg_out_of_bound_range(void)416*ecc42482SEduard Zingerman __naked void reg_out_of_bound_range(void)
417*ecc42482SEduard Zingerman {
418*ecc42482SEduard Zingerman asm volatile (" \
419*ecc42482SEduard Zingerman r2 = r10; \
420*ecc42482SEduard Zingerman r2 += -8; \
421*ecc42482SEduard Zingerman r1 = 0; \
422*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
423*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
424*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
425*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
426*ecc42482SEduard Zingerman r1 = r0; \
427*ecc42482SEduard Zingerman r3 = %[test_val_foo]; \
428*ecc42482SEduard Zingerman r1 += r3; \
429*ecc42482SEduard Zingerman r2 = %[__imm_0]; \
430*ecc42482SEduard Zingerman r3 = 0; \
431*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
432*ecc42482SEduard Zingerman l0_%=: exit; \
433*ecc42482SEduard Zingerman " :
434*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
435*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
436*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
437*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 8),
438*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
439*ecc42482SEduard Zingerman : __clobber_all);
440*ecc42482SEduard Zingerman }
441*ecc42482SEduard Zingerman
442*ecc42482SEduard Zingerman SEC("tracepoint")
443*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const reg): negative range (> adjustment)")
444*ecc42482SEduard Zingerman __failure __msg("R2 min value is negative")
const_reg_negative_range_adjustment_1(void)445*ecc42482SEduard Zingerman __naked void const_reg_negative_range_adjustment_1(void)
446*ecc42482SEduard Zingerman {
447*ecc42482SEduard Zingerman asm volatile (" \
448*ecc42482SEduard Zingerman r2 = r10; \
449*ecc42482SEduard Zingerman r2 += -8; \
450*ecc42482SEduard Zingerman r1 = 0; \
451*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
452*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
453*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
454*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
455*ecc42482SEduard Zingerman r1 = r0; \
456*ecc42482SEduard Zingerman r3 = %[test_val_foo]; \
457*ecc42482SEduard Zingerman r1 += r3; \
458*ecc42482SEduard Zingerman r2 = -8; \
459*ecc42482SEduard Zingerman r3 = 0; \
460*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
461*ecc42482SEduard Zingerman l0_%=: exit; \
462*ecc42482SEduard Zingerman " :
463*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
464*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
465*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
466*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
467*ecc42482SEduard Zingerman : __clobber_all);
468*ecc42482SEduard Zingerman }
469*ecc42482SEduard Zingerman
470*ecc42482SEduard Zingerman SEC("tracepoint")
471*ecc42482SEduard Zingerman __description("helper access to adjusted map (via const reg): negative range (< adjustment)")
472*ecc42482SEduard Zingerman __failure __msg("R2 min value is negative")
const_reg_negative_range_adjustment_2(void)473*ecc42482SEduard Zingerman __naked void const_reg_negative_range_adjustment_2(void)
474*ecc42482SEduard Zingerman {
475*ecc42482SEduard Zingerman asm volatile (" \
476*ecc42482SEduard Zingerman r2 = r10; \
477*ecc42482SEduard Zingerman r2 += -8; \
478*ecc42482SEduard Zingerman r1 = 0; \
479*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
480*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
481*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
482*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
483*ecc42482SEduard Zingerman r1 = r0; \
484*ecc42482SEduard Zingerman r3 = %[test_val_foo]; \
485*ecc42482SEduard Zingerman r1 += r3; \
486*ecc42482SEduard Zingerman r2 = -1; \
487*ecc42482SEduard Zingerman r3 = 0; \
488*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
489*ecc42482SEduard Zingerman l0_%=: exit; \
490*ecc42482SEduard Zingerman " :
491*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
492*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
493*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
494*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
495*ecc42482SEduard Zingerman : __clobber_all);
496*ecc42482SEduard Zingerman }
497*ecc42482SEduard Zingerman
498*ecc42482SEduard Zingerman SEC("tracepoint")
499*ecc42482SEduard Zingerman __description("helper access to adjusted map (via variable): full range")
500*ecc42482SEduard Zingerman __success
map_via_variable_full_range(void)501*ecc42482SEduard Zingerman __naked void map_via_variable_full_range(void)
502*ecc42482SEduard Zingerman {
503*ecc42482SEduard Zingerman asm volatile (" \
504*ecc42482SEduard Zingerman r2 = r10; \
505*ecc42482SEduard Zingerman r2 += -8; \
506*ecc42482SEduard Zingerman r1 = 0; \
507*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
508*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
509*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
510*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
511*ecc42482SEduard Zingerman r1 = r0; \
512*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
513*ecc42482SEduard Zingerman if r3 > %[test_val_foo] goto l0_%=; \
514*ecc42482SEduard Zingerman r1 += r3; \
515*ecc42482SEduard Zingerman r2 = %[__imm_0]; \
516*ecc42482SEduard Zingerman r3 = 0; \
517*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
518*ecc42482SEduard Zingerman l0_%=: exit; \
519*ecc42482SEduard Zingerman " :
520*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
521*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
522*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
523*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo)),
524*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
525*ecc42482SEduard Zingerman : __clobber_all);
526*ecc42482SEduard Zingerman }
527*ecc42482SEduard Zingerman
528*ecc42482SEduard Zingerman SEC("tracepoint")
529*ecc42482SEduard Zingerman __description("helper access to adjusted map (via variable): partial range")
530*ecc42482SEduard Zingerman __success
map_via_variable_partial_range(void)531*ecc42482SEduard Zingerman __naked void map_via_variable_partial_range(void)
532*ecc42482SEduard Zingerman {
533*ecc42482SEduard Zingerman asm volatile (" \
534*ecc42482SEduard Zingerman r2 = r10; \
535*ecc42482SEduard Zingerman r2 += -8; \
536*ecc42482SEduard Zingerman r1 = 0; \
537*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
538*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
539*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
540*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
541*ecc42482SEduard Zingerman r1 = r0; \
542*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
543*ecc42482SEduard Zingerman if r3 > %[test_val_foo] goto l0_%=; \
544*ecc42482SEduard Zingerman r1 += r3; \
545*ecc42482SEduard Zingerman r2 = 8; \
546*ecc42482SEduard Zingerman r3 = 0; \
547*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
548*ecc42482SEduard Zingerman l0_%=: exit; \
549*ecc42482SEduard Zingerman " :
550*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
551*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
552*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
553*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
554*ecc42482SEduard Zingerman : __clobber_all);
555*ecc42482SEduard Zingerman }
556*ecc42482SEduard Zingerman
557*ecc42482SEduard Zingerman SEC("tracepoint")
558*ecc42482SEduard Zingerman __description("helper access to adjusted map (via variable): empty range")
559*ecc42482SEduard Zingerman __failure __msg("R1 min value is outside of the allowed memory range")
map_via_variable_empty_range(void)560*ecc42482SEduard Zingerman __naked void map_via_variable_empty_range(void)
561*ecc42482SEduard Zingerman {
562*ecc42482SEduard Zingerman asm volatile (" \
563*ecc42482SEduard Zingerman r2 = r10; \
564*ecc42482SEduard Zingerman r2 += -8; \
565*ecc42482SEduard Zingerman r1 = 0; \
566*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
567*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
568*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
569*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
570*ecc42482SEduard Zingerman r1 = r0; \
571*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
572*ecc42482SEduard Zingerman if r3 > %[test_val_foo] goto l0_%=; \
573*ecc42482SEduard Zingerman r1 += r3; \
574*ecc42482SEduard Zingerman r2 = 0; \
575*ecc42482SEduard Zingerman call %[bpf_trace_printk]; \
576*ecc42482SEduard Zingerman l0_%=: exit; \
577*ecc42482SEduard Zingerman " :
578*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
579*ecc42482SEduard Zingerman __imm(bpf_trace_printk),
580*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
581*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
582*ecc42482SEduard Zingerman : __clobber_all);
583*ecc42482SEduard Zingerman }
584*ecc42482SEduard Zingerman
585*ecc42482SEduard Zingerman SEC("tracepoint")
586*ecc42482SEduard Zingerman __description("helper access to adjusted map (via variable): no max check")
587*ecc42482SEduard Zingerman __failure __msg("R1 unbounded memory access")
via_variable_no_max_check_1(void)588*ecc42482SEduard Zingerman __naked void via_variable_no_max_check_1(void)
589*ecc42482SEduard Zingerman {
590*ecc42482SEduard Zingerman asm volatile (" \
591*ecc42482SEduard Zingerman r2 = r10; \
592*ecc42482SEduard Zingerman r2 += -8; \
593*ecc42482SEduard Zingerman r1 = 0; \
594*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
595*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
596*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
597*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
598*ecc42482SEduard Zingerman r1 = r0; \
599*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
600*ecc42482SEduard Zingerman r1 += r3; \
601*ecc42482SEduard Zingerman r2 = 1; \
602*ecc42482SEduard Zingerman r3 = 0; \
603*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
604*ecc42482SEduard Zingerman l0_%=: exit; \
605*ecc42482SEduard Zingerman " :
606*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
607*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
608*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
609*ecc42482SEduard Zingerman : __clobber_all);
610*ecc42482SEduard Zingerman }
611*ecc42482SEduard Zingerman
612*ecc42482SEduard Zingerman SEC("tracepoint")
613*ecc42482SEduard Zingerman __description("helper access to adjusted map (via variable): wrong max check")
614*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=48 off=4 size=45")
via_variable_wrong_max_check_1(void)615*ecc42482SEduard Zingerman __naked void via_variable_wrong_max_check_1(void)
616*ecc42482SEduard Zingerman {
617*ecc42482SEduard Zingerman asm volatile (" \
618*ecc42482SEduard Zingerman r2 = r10; \
619*ecc42482SEduard Zingerman r2 += -8; \
620*ecc42482SEduard Zingerman r1 = 0; \
621*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
622*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
623*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
624*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
625*ecc42482SEduard Zingerman r1 = r0; \
626*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
627*ecc42482SEduard Zingerman if r3 > %[test_val_foo] goto l0_%=; \
628*ecc42482SEduard Zingerman r1 += r3; \
629*ecc42482SEduard Zingerman r2 = %[__imm_0]; \
630*ecc42482SEduard Zingerman r3 = 0; \
631*ecc42482SEduard Zingerman call %[bpf_probe_read_kernel]; \
632*ecc42482SEduard Zingerman l0_%=: exit; \
633*ecc42482SEduard Zingerman " :
634*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
635*ecc42482SEduard Zingerman __imm(bpf_probe_read_kernel),
636*ecc42482SEduard Zingerman __imm_addr(map_hash_48b),
637*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct test_val) - offsetof(struct test_val, foo) + 1),
638*ecc42482SEduard Zingerman __imm_const(test_val_foo, offsetof(struct test_val, foo))
639*ecc42482SEduard Zingerman : __clobber_all);
640*ecc42482SEduard Zingerman }
641*ecc42482SEduard Zingerman
642*ecc42482SEduard Zingerman SEC("tracepoint")
643*ecc42482SEduard Zingerman __description("helper access to map: bounds check using <, good access")
644*ecc42482SEduard Zingerman __success
bounds_check_using_good_access_1(void)645*ecc42482SEduard Zingerman __naked void bounds_check_using_good_access_1(void)
646*ecc42482SEduard Zingerman {
647*ecc42482SEduard Zingerman asm volatile (" \
648*ecc42482SEduard Zingerman r2 = r10; \
649*ecc42482SEduard Zingerman r2 += -8; \
650*ecc42482SEduard Zingerman r1 = 0; \
651*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
652*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
653*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
654*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
655*ecc42482SEduard Zingerman r1 = r0; \
656*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
657*ecc42482SEduard Zingerman if r3 < 32 goto l1_%=; \
658*ecc42482SEduard Zingerman r0 = 0; \
659*ecc42482SEduard Zingerman l0_%=: exit; \
660*ecc42482SEduard Zingerman l1_%=: r1 += r3; \
661*ecc42482SEduard Zingerman r0 = 0; \
662*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
663*ecc42482SEduard Zingerman r0 = 0; \
664*ecc42482SEduard Zingerman exit; \
665*ecc42482SEduard Zingerman " :
666*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
667*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
668*ecc42482SEduard Zingerman : __clobber_all);
669*ecc42482SEduard Zingerman }
670*ecc42482SEduard Zingerman
671*ecc42482SEduard Zingerman SEC("tracepoint")
672*ecc42482SEduard Zingerman __description("helper access to map: bounds check using <, bad access")
673*ecc42482SEduard Zingerman __failure __msg("R1 unbounded memory access")
bounds_check_using_bad_access_1(void)674*ecc42482SEduard Zingerman __naked void bounds_check_using_bad_access_1(void)
675*ecc42482SEduard Zingerman {
676*ecc42482SEduard Zingerman asm volatile (" \
677*ecc42482SEduard Zingerman r2 = r10; \
678*ecc42482SEduard Zingerman r2 += -8; \
679*ecc42482SEduard Zingerman r1 = 0; \
680*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
681*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
682*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
683*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
684*ecc42482SEduard Zingerman r1 = r0; \
685*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
686*ecc42482SEduard Zingerman if r3 < 32 goto l1_%=; \
687*ecc42482SEduard Zingerman r1 += r3; \
688*ecc42482SEduard Zingerman l0_%=: r0 = 0; \
689*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
690*ecc42482SEduard Zingerman r0 = 0; \
691*ecc42482SEduard Zingerman exit; \
692*ecc42482SEduard Zingerman l1_%=: r0 = 0; \
693*ecc42482SEduard Zingerman exit; \
694*ecc42482SEduard Zingerman " :
695*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
696*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
697*ecc42482SEduard Zingerman : __clobber_all);
698*ecc42482SEduard Zingerman }
699*ecc42482SEduard Zingerman
700*ecc42482SEduard Zingerman SEC("tracepoint")
701*ecc42482SEduard Zingerman __description("helper access to map: bounds check using <=, good access")
702*ecc42482SEduard Zingerman __success
bounds_check_using_good_access_2(void)703*ecc42482SEduard Zingerman __naked void bounds_check_using_good_access_2(void)
704*ecc42482SEduard Zingerman {
705*ecc42482SEduard Zingerman asm volatile (" \
706*ecc42482SEduard Zingerman r2 = r10; \
707*ecc42482SEduard Zingerman r2 += -8; \
708*ecc42482SEduard Zingerman r1 = 0; \
709*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
710*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
711*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
712*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
713*ecc42482SEduard Zingerman r1 = r0; \
714*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
715*ecc42482SEduard Zingerman if r3 <= 32 goto l1_%=; \
716*ecc42482SEduard Zingerman r0 = 0; \
717*ecc42482SEduard Zingerman l0_%=: exit; \
718*ecc42482SEduard Zingerman l1_%=: r1 += r3; \
719*ecc42482SEduard Zingerman r0 = 0; \
720*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
721*ecc42482SEduard Zingerman r0 = 0; \
722*ecc42482SEduard Zingerman exit; \
723*ecc42482SEduard Zingerman " :
724*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
725*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
726*ecc42482SEduard Zingerman : __clobber_all);
727*ecc42482SEduard Zingerman }
728*ecc42482SEduard Zingerman
729*ecc42482SEduard Zingerman SEC("tracepoint")
730*ecc42482SEduard Zingerman __description("helper access to map: bounds check using <=, bad access")
731*ecc42482SEduard Zingerman __failure __msg("R1 unbounded memory access")
bounds_check_using_bad_access_2(void)732*ecc42482SEduard Zingerman __naked void bounds_check_using_bad_access_2(void)
733*ecc42482SEduard Zingerman {
734*ecc42482SEduard Zingerman asm volatile (" \
735*ecc42482SEduard Zingerman r2 = r10; \
736*ecc42482SEduard Zingerman r2 += -8; \
737*ecc42482SEduard Zingerman r1 = 0; \
738*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
739*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
740*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
741*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
742*ecc42482SEduard Zingerman r1 = r0; \
743*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
744*ecc42482SEduard Zingerman if r3 <= 32 goto l1_%=; \
745*ecc42482SEduard Zingerman r1 += r3; \
746*ecc42482SEduard Zingerman l0_%=: r0 = 0; \
747*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
748*ecc42482SEduard Zingerman r0 = 0; \
749*ecc42482SEduard Zingerman exit; \
750*ecc42482SEduard Zingerman l1_%=: r0 = 0; \
751*ecc42482SEduard Zingerman exit; \
752*ecc42482SEduard Zingerman " :
753*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
754*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
755*ecc42482SEduard Zingerman : __clobber_all);
756*ecc42482SEduard Zingerman }
757*ecc42482SEduard Zingerman
758*ecc42482SEduard Zingerman SEC("tracepoint")
759*ecc42482SEduard Zingerman __description("helper access to map: bounds check using s<, good access")
760*ecc42482SEduard Zingerman __success
check_using_s_good_access_1(void)761*ecc42482SEduard Zingerman __naked void check_using_s_good_access_1(void)
762*ecc42482SEduard Zingerman {
763*ecc42482SEduard Zingerman asm volatile (" \
764*ecc42482SEduard Zingerman r2 = r10; \
765*ecc42482SEduard Zingerman r2 += -8; \
766*ecc42482SEduard Zingerman r1 = 0; \
767*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
768*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
769*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
770*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
771*ecc42482SEduard Zingerman r1 = r0; \
772*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
773*ecc42482SEduard Zingerman if r3 s< 32 goto l1_%=; \
774*ecc42482SEduard Zingerman l2_%=: r0 = 0; \
775*ecc42482SEduard Zingerman l0_%=: exit; \
776*ecc42482SEduard Zingerman l1_%=: if r3 s< 0 goto l2_%=; \
777*ecc42482SEduard Zingerman r1 += r3; \
778*ecc42482SEduard Zingerman r0 = 0; \
779*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
780*ecc42482SEduard Zingerman r0 = 0; \
781*ecc42482SEduard Zingerman exit; \
782*ecc42482SEduard Zingerman " :
783*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
784*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
785*ecc42482SEduard Zingerman : __clobber_all);
786*ecc42482SEduard Zingerman }
787*ecc42482SEduard Zingerman
788*ecc42482SEduard Zingerman SEC("tracepoint")
789*ecc42482SEduard Zingerman __description("helper access to map: bounds check using s<, good access 2")
790*ecc42482SEduard Zingerman __success
using_s_good_access_2_1(void)791*ecc42482SEduard Zingerman __naked void using_s_good_access_2_1(void)
792*ecc42482SEduard Zingerman {
793*ecc42482SEduard Zingerman asm volatile (" \
794*ecc42482SEduard Zingerman r2 = r10; \
795*ecc42482SEduard Zingerman r2 += -8; \
796*ecc42482SEduard Zingerman r1 = 0; \
797*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
798*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
799*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
800*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
801*ecc42482SEduard Zingerman r1 = r0; \
802*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
803*ecc42482SEduard Zingerman if r3 s< 32 goto l1_%=; \
804*ecc42482SEduard Zingerman l2_%=: r0 = 0; \
805*ecc42482SEduard Zingerman l0_%=: exit; \
806*ecc42482SEduard Zingerman l1_%=: if r3 s< -3 goto l2_%=; \
807*ecc42482SEduard Zingerman r1 += r3; \
808*ecc42482SEduard Zingerman r0 = 0; \
809*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
810*ecc42482SEduard Zingerman r0 = 0; \
811*ecc42482SEduard Zingerman exit; \
812*ecc42482SEduard Zingerman " :
813*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
814*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
815*ecc42482SEduard Zingerman : __clobber_all);
816*ecc42482SEduard Zingerman }
817*ecc42482SEduard Zingerman
818*ecc42482SEduard Zingerman SEC("tracepoint")
819*ecc42482SEduard Zingerman __description("helper access to map: bounds check using s<, bad access")
820*ecc42482SEduard Zingerman __failure __msg("R1 min value is negative")
check_using_s_bad_access_1(void)821*ecc42482SEduard Zingerman __naked void check_using_s_bad_access_1(void)
822*ecc42482SEduard Zingerman {
823*ecc42482SEduard Zingerman asm volatile (" \
824*ecc42482SEduard Zingerman r2 = r10; \
825*ecc42482SEduard Zingerman r2 += -8; \
826*ecc42482SEduard Zingerman r1 = 0; \
827*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
828*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
829*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
830*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
831*ecc42482SEduard Zingerman r1 = r0; \
832*ecc42482SEduard Zingerman r3 = *(u64*)(r0 + 0); \
833*ecc42482SEduard Zingerman if r3 s< 32 goto l1_%=; \
834*ecc42482SEduard Zingerman l2_%=: r0 = 0; \
835*ecc42482SEduard Zingerman l0_%=: exit; \
836*ecc42482SEduard Zingerman l1_%=: if r3 s< -3 goto l2_%=; \
837*ecc42482SEduard Zingerman r1 += r3; \
838*ecc42482SEduard Zingerman r0 = 0; \
839*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
840*ecc42482SEduard Zingerman r0 = 0; \
841*ecc42482SEduard Zingerman exit; \
842*ecc42482SEduard Zingerman " :
843*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
844*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
845*ecc42482SEduard Zingerman : __clobber_all);
846*ecc42482SEduard Zingerman }
847*ecc42482SEduard Zingerman
848*ecc42482SEduard Zingerman SEC("tracepoint")
849*ecc42482SEduard Zingerman __description("helper access to map: bounds check using s<=, good access")
850*ecc42482SEduard Zingerman __success
check_using_s_good_access_2(void)851*ecc42482SEduard Zingerman __naked void check_using_s_good_access_2(void)
852*ecc42482SEduard Zingerman {
853*ecc42482SEduard Zingerman asm volatile (" \
854*ecc42482SEduard Zingerman r2 = r10; \
855*ecc42482SEduard Zingerman r2 += -8; \
856*ecc42482SEduard Zingerman r1 = 0; \
857*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
858*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
859*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
860*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
861*ecc42482SEduard Zingerman r1 = r0; \
862*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
863*ecc42482SEduard Zingerman if r3 s<= 32 goto l1_%=; \
864*ecc42482SEduard Zingerman l2_%=: r0 = 0; \
865*ecc42482SEduard Zingerman l0_%=: exit; \
866*ecc42482SEduard Zingerman l1_%=: if r3 s<= 0 goto l2_%=; \
867*ecc42482SEduard Zingerman r1 += r3; \
868*ecc42482SEduard Zingerman r0 = 0; \
869*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
870*ecc42482SEduard Zingerman r0 = 0; \
871*ecc42482SEduard Zingerman exit; \
872*ecc42482SEduard Zingerman " :
873*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
874*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
875*ecc42482SEduard Zingerman : __clobber_all);
876*ecc42482SEduard Zingerman }
877*ecc42482SEduard Zingerman
878*ecc42482SEduard Zingerman SEC("tracepoint")
879*ecc42482SEduard Zingerman __description("helper access to map: bounds check using s<=, good access 2")
880*ecc42482SEduard Zingerman __success
using_s_good_access_2_2(void)881*ecc42482SEduard Zingerman __naked void using_s_good_access_2_2(void)
882*ecc42482SEduard Zingerman {
883*ecc42482SEduard Zingerman asm volatile (" \
884*ecc42482SEduard Zingerman r2 = r10; \
885*ecc42482SEduard Zingerman r2 += -8; \
886*ecc42482SEduard Zingerman r1 = 0; \
887*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
888*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
889*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
890*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
891*ecc42482SEduard Zingerman r1 = r0; \
892*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
893*ecc42482SEduard Zingerman if r3 s<= 32 goto l1_%=; \
894*ecc42482SEduard Zingerman l2_%=: r0 = 0; \
895*ecc42482SEduard Zingerman l0_%=: exit; \
896*ecc42482SEduard Zingerman l1_%=: if r3 s<= -3 goto l2_%=; \
897*ecc42482SEduard Zingerman r1 += r3; \
898*ecc42482SEduard Zingerman r0 = 0; \
899*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
900*ecc42482SEduard Zingerman r0 = 0; \
901*ecc42482SEduard Zingerman exit; \
902*ecc42482SEduard Zingerman " :
903*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
904*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
905*ecc42482SEduard Zingerman : __clobber_all);
906*ecc42482SEduard Zingerman }
907*ecc42482SEduard Zingerman
908*ecc42482SEduard Zingerman SEC("tracepoint")
909*ecc42482SEduard Zingerman __description("helper access to map: bounds check using s<=, bad access")
910*ecc42482SEduard Zingerman __failure __msg("R1 min value is negative")
check_using_s_bad_access_2(void)911*ecc42482SEduard Zingerman __naked void check_using_s_bad_access_2(void)
912*ecc42482SEduard Zingerman {
913*ecc42482SEduard Zingerman asm volatile (" \
914*ecc42482SEduard Zingerman r2 = r10; \
915*ecc42482SEduard Zingerman r2 += -8; \
916*ecc42482SEduard Zingerman r1 = 0; \
917*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
918*ecc42482SEduard Zingerman r1 = %[map_hash_48b] ll; \
919*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
920*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
921*ecc42482SEduard Zingerman r1 = r0; \
922*ecc42482SEduard Zingerman r3 = *(u64*)(r0 + 0); \
923*ecc42482SEduard Zingerman if r3 s<= 32 goto l1_%=; \
924*ecc42482SEduard Zingerman l2_%=: r0 = 0; \
925*ecc42482SEduard Zingerman l0_%=: exit; \
926*ecc42482SEduard Zingerman l1_%=: if r3 s<= -3 goto l2_%=; \
927*ecc42482SEduard Zingerman r1 += r3; \
928*ecc42482SEduard Zingerman r0 = 0; \
929*ecc42482SEduard Zingerman *(u8*)(r1 + 0) = r0; \
930*ecc42482SEduard Zingerman r0 = 0; \
931*ecc42482SEduard Zingerman exit; \
932*ecc42482SEduard Zingerman " :
933*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
934*ecc42482SEduard Zingerman __imm_addr(map_hash_48b)
935*ecc42482SEduard Zingerman : __clobber_all);
936*ecc42482SEduard Zingerman }
937*ecc42482SEduard Zingerman
938*ecc42482SEduard Zingerman SEC("tracepoint")
939*ecc42482SEduard Zingerman __description("map lookup helper access to map")
940*ecc42482SEduard Zingerman __success
lookup_helper_access_to_map(void)941*ecc42482SEduard Zingerman __naked void lookup_helper_access_to_map(void)
942*ecc42482SEduard Zingerman {
943*ecc42482SEduard Zingerman asm volatile (" \
944*ecc42482SEduard Zingerman r2 = r10; \
945*ecc42482SEduard Zingerman r2 += -8; \
946*ecc42482SEduard Zingerman r1 = 0; \
947*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
948*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
949*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
950*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
951*ecc42482SEduard Zingerman r2 = r0; \
952*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
953*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
954*ecc42482SEduard Zingerman l0_%=: exit; \
955*ecc42482SEduard Zingerman " :
956*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
957*ecc42482SEduard Zingerman __imm_addr(map_hash_16b)
958*ecc42482SEduard Zingerman : __clobber_all);
959*ecc42482SEduard Zingerman }
960*ecc42482SEduard Zingerman
961*ecc42482SEduard Zingerman SEC("tracepoint")
962*ecc42482SEduard Zingerman __description("map update helper access to map")
963*ecc42482SEduard Zingerman __success
update_helper_access_to_map(void)964*ecc42482SEduard Zingerman __naked void update_helper_access_to_map(void)
965*ecc42482SEduard Zingerman {
966*ecc42482SEduard Zingerman asm volatile (" \
967*ecc42482SEduard Zingerman r2 = r10; \
968*ecc42482SEduard Zingerman r2 += -8; \
969*ecc42482SEduard Zingerman r1 = 0; \
970*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
971*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
972*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
973*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
974*ecc42482SEduard Zingerman r4 = 0; \
975*ecc42482SEduard Zingerman r3 = r0; \
976*ecc42482SEduard Zingerman r2 = r0; \
977*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
978*ecc42482SEduard Zingerman call %[bpf_map_update_elem]; \
979*ecc42482SEduard Zingerman l0_%=: exit; \
980*ecc42482SEduard Zingerman " :
981*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
982*ecc42482SEduard Zingerman __imm(bpf_map_update_elem),
983*ecc42482SEduard Zingerman __imm_addr(map_hash_16b)
984*ecc42482SEduard Zingerman : __clobber_all);
985*ecc42482SEduard Zingerman }
986*ecc42482SEduard Zingerman
987*ecc42482SEduard Zingerman SEC("tracepoint")
988*ecc42482SEduard Zingerman __description("map update helper access to map: wrong size")
989*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=8 off=0 size=16")
access_to_map_wrong_size(void)990*ecc42482SEduard Zingerman __naked void access_to_map_wrong_size(void)
991*ecc42482SEduard Zingerman {
992*ecc42482SEduard Zingerman asm volatile (" \
993*ecc42482SEduard Zingerman r2 = r10; \
994*ecc42482SEduard Zingerman r2 += -8; \
995*ecc42482SEduard Zingerman r1 = 0; \
996*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
997*ecc42482SEduard Zingerman r1 = %[map_hash_8b] ll; \
998*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
999*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1000*ecc42482SEduard Zingerman r4 = 0; \
1001*ecc42482SEduard Zingerman r3 = r0; \
1002*ecc42482SEduard Zingerman r2 = r0; \
1003*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1004*ecc42482SEduard Zingerman call %[bpf_map_update_elem]; \
1005*ecc42482SEduard Zingerman l0_%=: exit; \
1006*ecc42482SEduard Zingerman " :
1007*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1008*ecc42482SEduard Zingerman __imm(bpf_map_update_elem),
1009*ecc42482SEduard Zingerman __imm_addr(map_hash_16b),
1010*ecc42482SEduard Zingerman __imm_addr(map_hash_8b)
1011*ecc42482SEduard Zingerman : __clobber_all);
1012*ecc42482SEduard Zingerman }
1013*ecc42482SEduard Zingerman
1014*ecc42482SEduard Zingerman SEC("tracepoint")
1015*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via const imm)")
1016*ecc42482SEduard Zingerman __success
adjusted_map_via_const_imm(void)1017*ecc42482SEduard Zingerman __naked void adjusted_map_via_const_imm(void)
1018*ecc42482SEduard Zingerman {
1019*ecc42482SEduard Zingerman asm volatile (" \
1020*ecc42482SEduard Zingerman r2 = r10; \
1021*ecc42482SEduard Zingerman r2 += -8; \
1022*ecc42482SEduard Zingerman r1 = 0; \
1023*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1024*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1025*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1026*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1027*ecc42482SEduard Zingerman r2 = r0; \
1028*ecc42482SEduard Zingerman r2 += %[other_val_bar]; \
1029*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1030*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1031*ecc42482SEduard Zingerman l0_%=: exit; \
1032*ecc42482SEduard Zingerman " :
1033*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1034*ecc42482SEduard Zingerman __imm_addr(map_hash_16b),
1035*ecc42482SEduard Zingerman __imm_const(other_val_bar, offsetof(struct other_val, bar))
1036*ecc42482SEduard Zingerman : __clobber_all);
1037*ecc42482SEduard Zingerman }
1038*ecc42482SEduard Zingerman
1039*ecc42482SEduard Zingerman SEC("tracepoint")
1040*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via const imm): out-of-bound 1")
1041*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=16 off=12 size=8")
imm_out_of_bound_1(void)1042*ecc42482SEduard Zingerman __naked void imm_out_of_bound_1(void)
1043*ecc42482SEduard Zingerman {
1044*ecc42482SEduard Zingerman asm volatile (" \
1045*ecc42482SEduard Zingerman r2 = r10; \
1046*ecc42482SEduard Zingerman r2 += -8; \
1047*ecc42482SEduard Zingerman r1 = 0; \
1048*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1049*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1050*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1051*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1052*ecc42482SEduard Zingerman r2 = r0; \
1053*ecc42482SEduard Zingerman r2 += %[__imm_0]; \
1054*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1055*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1056*ecc42482SEduard Zingerman l0_%=: exit; \
1057*ecc42482SEduard Zingerman " :
1058*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1059*ecc42482SEduard Zingerman __imm_addr(map_hash_16b),
1060*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct other_val) - 4)
1061*ecc42482SEduard Zingerman : __clobber_all);
1062*ecc42482SEduard Zingerman }
1063*ecc42482SEduard Zingerman
1064*ecc42482SEduard Zingerman SEC("tracepoint")
1065*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via const imm): out-of-bound 2")
1066*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=16 off=-4 size=8")
imm_out_of_bound_2(void)1067*ecc42482SEduard Zingerman __naked void imm_out_of_bound_2(void)
1068*ecc42482SEduard Zingerman {
1069*ecc42482SEduard Zingerman asm volatile (" \
1070*ecc42482SEduard Zingerman r2 = r10; \
1071*ecc42482SEduard Zingerman r2 += -8; \
1072*ecc42482SEduard Zingerman r1 = 0; \
1073*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1074*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1075*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1076*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1077*ecc42482SEduard Zingerman r2 = r0; \
1078*ecc42482SEduard Zingerman r2 += -4; \
1079*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1080*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1081*ecc42482SEduard Zingerman l0_%=: exit; \
1082*ecc42482SEduard Zingerman " :
1083*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1084*ecc42482SEduard Zingerman __imm_addr(map_hash_16b)
1085*ecc42482SEduard Zingerman : __clobber_all);
1086*ecc42482SEduard Zingerman }
1087*ecc42482SEduard Zingerman
1088*ecc42482SEduard Zingerman SEC("tracepoint")
1089*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via const reg)")
1090*ecc42482SEduard Zingerman __success
adjusted_map_via_const_reg(void)1091*ecc42482SEduard Zingerman __naked void adjusted_map_via_const_reg(void)
1092*ecc42482SEduard Zingerman {
1093*ecc42482SEduard Zingerman asm volatile (" \
1094*ecc42482SEduard Zingerman r2 = r10; \
1095*ecc42482SEduard Zingerman r2 += -8; \
1096*ecc42482SEduard Zingerman r1 = 0; \
1097*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1098*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1099*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1100*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1101*ecc42482SEduard Zingerman r2 = r0; \
1102*ecc42482SEduard Zingerman r3 = %[other_val_bar]; \
1103*ecc42482SEduard Zingerman r2 += r3; \
1104*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1105*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1106*ecc42482SEduard Zingerman l0_%=: exit; \
1107*ecc42482SEduard Zingerman " :
1108*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1109*ecc42482SEduard Zingerman __imm_addr(map_hash_16b),
1110*ecc42482SEduard Zingerman __imm_const(other_val_bar, offsetof(struct other_val, bar))
1111*ecc42482SEduard Zingerman : __clobber_all);
1112*ecc42482SEduard Zingerman }
1113*ecc42482SEduard Zingerman
1114*ecc42482SEduard Zingerman SEC("tracepoint")
1115*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via const reg): out-of-bound 1")
1116*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=16 off=12 size=8")
reg_out_of_bound_1(void)1117*ecc42482SEduard Zingerman __naked void reg_out_of_bound_1(void)
1118*ecc42482SEduard Zingerman {
1119*ecc42482SEduard Zingerman asm volatile (" \
1120*ecc42482SEduard Zingerman r2 = r10; \
1121*ecc42482SEduard Zingerman r2 += -8; \
1122*ecc42482SEduard Zingerman r1 = 0; \
1123*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1124*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1125*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1126*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1127*ecc42482SEduard Zingerman r2 = r0; \
1128*ecc42482SEduard Zingerman r3 = %[__imm_0]; \
1129*ecc42482SEduard Zingerman r2 += r3; \
1130*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1131*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1132*ecc42482SEduard Zingerman l0_%=: exit; \
1133*ecc42482SEduard Zingerman " :
1134*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1135*ecc42482SEduard Zingerman __imm_addr(map_hash_16b),
1136*ecc42482SEduard Zingerman __imm_const(__imm_0, sizeof(struct other_val) - 4)
1137*ecc42482SEduard Zingerman : __clobber_all);
1138*ecc42482SEduard Zingerman }
1139*ecc42482SEduard Zingerman
1140*ecc42482SEduard Zingerman SEC("tracepoint")
1141*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via const reg): out-of-bound 2")
1142*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=16 off=-4 size=8")
reg_out_of_bound_2(void)1143*ecc42482SEduard Zingerman __naked void reg_out_of_bound_2(void)
1144*ecc42482SEduard Zingerman {
1145*ecc42482SEduard Zingerman asm volatile (" \
1146*ecc42482SEduard Zingerman r2 = r10; \
1147*ecc42482SEduard Zingerman r2 += -8; \
1148*ecc42482SEduard Zingerman r1 = 0; \
1149*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1150*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1151*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1152*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1153*ecc42482SEduard Zingerman r2 = r0; \
1154*ecc42482SEduard Zingerman r3 = -4; \
1155*ecc42482SEduard Zingerman r2 += r3; \
1156*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1157*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1158*ecc42482SEduard Zingerman l0_%=: exit; \
1159*ecc42482SEduard Zingerman " :
1160*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1161*ecc42482SEduard Zingerman __imm_addr(map_hash_16b)
1162*ecc42482SEduard Zingerman : __clobber_all);
1163*ecc42482SEduard Zingerman }
1164*ecc42482SEduard Zingerman
1165*ecc42482SEduard Zingerman SEC("tracepoint")
1166*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via variable)")
1167*ecc42482SEduard Zingerman __success
to_adjusted_map_via_variable(void)1168*ecc42482SEduard Zingerman __naked void to_adjusted_map_via_variable(void)
1169*ecc42482SEduard Zingerman {
1170*ecc42482SEduard Zingerman asm volatile (" \
1171*ecc42482SEduard Zingerman r2 = r10; \
1172*ecc42482SEduard Zingerman r2 += -8; \
1173*ecc42482SEduard Zingerman r1 = 0; \
1174*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1175*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1176*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1177*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1178*ecc42482SEduard Zingerman r2 = r0; \
1179*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
1180*ecc42482SEduard Zingerman if r3 > %[other_val_bar] goto l0_%=; \
1181*ecc42482SEduard Zingerman r2 += r3; \
1182*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1183*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1184*ecc42482SEduard Zingerman l0_%=: exit; \
1185*ecc42482SEduard Zingerman " :
1186*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1187*ecc42482SEduard Zingerman __imm_addr(map_hash_16b),
1188*ecc42482SEduard Zingerman __imm_const(other_val_bar, offsetof(struct other_val, bar))
1189*ecc42482SEduard Zingerman : __clobber_all);
1190*ecc42482SEduard Zingerman }
1191*ecc42482SEduard Zingerman
1192*ecc42482SEduard Zingerman SEC("tracepoint")
1193*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via variable): no max check")
1194*ecc42482SEduard Zingerman __failure
1195*ecc42482SEduard Zingerman __msg("R2 unbounded memory access, make sure to bounds check any such access")
via_variable_no_max_check_2(void)1196*ecc42482SEduard Zingerman __naked void via_variable_no_max_check_2(void)
1197*ecc42482SEduard Zingerman {
1198*ecc42482SEduard Zingerman asm volatile (" \
1199*ecc42482SEduard Zingerman r2 = r10; \
1200*ecc42482SEduard Zingerman r2 += -8; \
1201*ecc42482SEduard Zingerman r1 = 0; \
1202*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1203*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1204*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1205*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1206*ecc42482SEduard Zingerman r2 = r0; \
1207*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
1208*ecc42482SEduard Zingerman r2 += r3; \
1209*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1210*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1211*ecc42482SEduard Zingerman l0_%=: exit; \
1212*ecc42482SEduard Zingerman " :
1213*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1214*ecc42482SEduard Zingerman __imm_addr(map_hash_16b)
1215*ecc42482SEduard Zingerman : __clobber_all);
1216*ecc42482SEduard Zingerman }
1217*ecc42482SEduard Zingerman
1218*ecc42482SEduard Zingerman SEC("tracepoint")
1219*ecc42482SEduard Zingerman __description("map helper access to adjusted map (via variable): wrong max check")
1220*ecc42482SEduard Zingerman __failure __msg("invalid access to map value, value_size=16 off=9 size=8")
via_variable_wrong_max_check_2(void)1221*ecc42482SEduard Zingerman __naked void via_variable_wrong_max_check_2(void)
1222*ecc42482SEduard Zingerman {
1223*ecc42482SEduard Zingerman asm volatile (" \
1224*ecc42482SEduard Zingerman r2 = r10; \
1225*ecc42482SEduard Zingerman r2 += -8; \
1226*ecc42482SEduard Zingerman r1 = 0; \
1227*ecc42482SEduard Zingerman *(u64*)(r2 + 0) = r1; \
1228*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1229*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1230*ecc42482SEduard Zingerman if r0 == 0 goto l0_%=; \
1231*ecc42482SEduard Zingerman r2 = r0; \
1232*ecc42482SEduard Zingerman r3 = *(u32*)(r0 + 0); \
1233*ecc42482SEduard Zingerman if r3 > %[__imm_0] goto l0_%=; \
1234*ecc42482SEduard Zingerman r2 += r3; \
1235*ecc42482SEduard Zingerman r1 = %[map_hash_16b] ll; \
1236*ecc42482SEduard Zingerman call %[bpf_map_lookup_elem]; \
1237*ecc42482SEduard Zingerman l0_%=: exit; \
1238*ecc42482SEduard Zingerman " :
1239*ecc42482SEduard Zingerman : __imm(bpf_map_lookup_elem),
1240*ecc42482SEduard Zingerman __imm_addr(map_hash_16b),
1241*ecc42482SEduard Zingerman __imm_const(__imm_0, offsetof(struct other_val, bar) + 1)
1242*ecc42482SEduard Zingerman : __clobber_all);
1243*ecc42482SEduard Zingerman }
1244*ecc42482SEduard Zingerman
1245*ecc42482SEduard Zingerman char _license[] SEC("license") = "GPL";
1246