1*edff37b2SEduard Zingerman // SPDX-License-Identifier: GPL-2.0
2*edff37b2SEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/stack_ptr.c */
3*edff37b2SEduard Zingerman
4*edff37b2SEduard Zingerman #include <linux/bpf.h>
5*edff37b2SEduard Zingerman #include <bpf/bpf_helpers.h>
6*edff37b2SEduard Zingerman #include <limits.h>
7*edff37b2SEduard Zingerman #include "bpf_misc.h"
8*edff37b2SEduard Zingerman
9*edff37b2SEduard Zingerman #define MAX_ENTRIES 11
10*edff37b2SEduard Zingerman
11*edff37b2SEduard Zingerman struct test_val {
12*edff37b2SEduard Zingerman unsigned int index;
13*edff37b2SEduard Zingerman int foo[MAX_ENTRIES];
14*edff37b2SEduard Zingerman };
15*edff37b2SEduard Zingerman
16*edff37b2SEduard Zingerman struct {
17*edff37b2SEduard Zingerman __uint(type, BPF_MAP_TYPE_ARRAY);
18*edff37b2SEduard Zingerman __uint(max_entries, 1);
19*edff37b2SEduard Zingerman __type(key, int);
20*edff37b2SEduard Zingerman __type(value, struct test_val);
21*edff37b2SEduard Zingerman } map_array_48b SEC(".maps");
22*edff37b2SEduard Zingerman
23*edff37b2SEduard Zingerman SEC("socket")
24*edff37b2SEduard Zingerman __description("PTR_TO_STACK store/load")
25*edff37b2SEduard Zingerman __success __success_unpriv __retval(0xfaceb00c)
ptr_to_stack_store_load(void)26*edff37b2SEduard Zingerman __naked void ptr_to_stack_store_load(void)
27*edff37b2SEduard Zingerman {
28*edff37b2SEduard Zingerman asm volatile (" \
29*edff37b2SEduard Zingerman r1 = r10; \
30*edff37b2SEduard Zingerman r1 += -10; \
31*edff37b2SEduard Zingerman r0 = 0xfaceb00c; \
32*edff37b2SEduard Zingerman *(u64*)(r1 + 2) = r0; \
33*edff37b2SEduard Zingerman r0 = *(u64*)(r1 + 2); \
34*edff37b2SEduard Zingerman exit; \
35*edff37b2SEduard Zingerman " ::: __clobber_all);
36*edff37b2SEduard Zingerman }
37*edff37b2SEduard Zingerman
38*edff37b2SEduard Zingerman SEC("socket")
39*edff37b2SEduard Zingerman __description("PTR_TO_STACK store/load - bad alignment on off")
40*edff37b2SEduard Zingerman __failure __msg("misaligned stack access off (0x0; 0x0)+-8+2 size 8")
41*edff37b2SEduard Zingerman __failure_unpriv
load_bad_alignment_on_off(void)42*edff37b2SEduard Zingerman __naked void load_bad_alignment_on_off(void)
43*edff37b2SEduard Zingerman {
44*edff37b2SEduard Zingerman asm volatile (" \
45*edff37b2SEduard Zingerman r1 = r10; \
46*edff37b2SEduard Zingerman r1 += -8; \
47*edff37b2SEduard Zingerman r0 = 0xfaceb00c; \
48*edff37b2SEduard Zingerman *(u64*)(r1 + 2) = r0; \
49*edff37b2SEduard Zingerman r0 = *(u64*)(r1 + 2); \
50*edff37b2SEduard Zingerman exit; \
51*edff37b2SEduard Zingerman " ::: __clobber_all);
52*edff37b2SEduard Zingerman }
53*edff37b2SEduard Zingerman
54*edff37b2SEduard Zingerman SEC("socket")
55*edff37b2SEduard Zingerman __description("PTR_TO_STACK store/load - bad alignment on reg")
56*edff37b2SEduard Zingerman __failure __msg("misaligned stack access off (0x0; 0x0)+-10+8 size 8")
57*edff37b2SEduard Zingerman __failure_unpriv
load_bad_alignment_on_reg(void)58*edff37b2SEduard Zingerman __naked void load_bad_alignment_on_reg(void)
59*edff37b2SEduard Zingerman {
60*edff37b2SEduard Zingerman asm volatile (" \
61*edff37b2SEduard Zingerman r1 = r10; \
62*edff37b2SEduard Zingerman r1 += -10; \
63*edff37b2SEduard Zingerman r0 = 0xfaceb00c; \
64*edff37b2SEduard Zingerman *(u64*)(r1 + 8) = r0; \
65*edff37b2SEduard Zingerman r0 = *(u64*)(r1 + 8); \
66*edff37b2SEduard Zingerman exit; \
67*edff37b2SEduard Zingerman " ::: __clobber_all);
68*edff37b2SEduard Zingerman }
69*edff37b2SEduard Zingerman
70*edff37b2SEduard Zingerman SEC("socket")
71*edff37b2SEduard Zingerman __description("PTR_TO_STACK store/load - out of bounds low")
72*edff37b2SEduard Zingerman __failure __msg("invalid write to stack R1 off=-79992 size=8")
73*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
load_out_of_bounds_low(void)74*edff37b2SEduard Zingerman __naked void load_out_of_bounds_low(void)
75*edff37b2SEduard Zingerman {
76*edff37b2SEduard Zingerman asm volatile (" \
77*edff37b2SEduard Zingerman r1 = r10; \
78*edff37b2SEduard Zingerman r1 += -80000; \
79*edff37b2SEduard Zingerman r0 = 0xfaceb00c; \
80*edff37b2SEduard Zingerman *(u64*)(r1 + 8) = r0; \
81*edff37b2SEduard Zingerman r0 = *(u64*)(r1 + 8); \
82*edff37b2SEduard Zingerman exit; \
83*edff37b2SEduard Zingerman " ::: __clobber_all);
84*edff37b2SEduard Zingerman }
85*edff37b2SEduard Zingerman
86*edff37b2SEduard Zingerman SEC("socket")
87*edff37b2SEduard Zingerman __description("PTR_TO_STACK store/load - out of bounds high")
88*edff37b2SEduard Zingerman __failure __msg("invalid write to stack R1 off=0 size=8")
89*edff37b2SEduard Zingerman __failure_unpriv
load_out_of_bounds_high(void)90*edff37b2SEduard Zingerman __naked void load_out_of_bounds_high(void)
91*edff37b2SEduard Zingerman {
92*edff37b2SEduard Zingerman asm volatile (" \
93*edff37b2SEduard Zingerman r1 = r10; \
94*edff37b2SEduard Zingerman r1 += -8; \
95*edff37b2SEduard Zingerman r0 = 0xfaceb00c; \
96*edff37b2SEduard Zingerman *(u64*)(r1 + 8) = r0; \
97*edff37b2SEduard Zingerman r0 = *(u64*)(r1 + 8); \
98*edff37b2SEduard Zingerman exit; \
99*edff37b2SEduard Zingerman " ::: __clobber_all);
100*edff37b2SEduard Zingerman }
101*edff37b2SEduard Zingerman
102*edff37b2SEduard Zingerman SEC("socket")
103*edff37b2SEduard Zingerman __description("PTR_TO_STACK check high 1")
104*edff37b2SEduard Zingerman __success __success_unpriv __retval(42)
to_stack_check_high_1(void)105*edff37b2SEduard Zingerman __naked void to_stack_check_high_1(void)
106*edff37b2SEduard Zingerman {
107*edff37b2SEduard Zingerman asm volatile (" \
108*edff37b2SEduard Zingerman r1 = r10; \
109*edff37b2SEduard Zingerman r1 += -1; \
110*edff37b2SEduard Zingerman r0 = 42; \
111*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
112*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
113*edff37b2SEduard Zingerman exit; \
114*edff37b2SEduard Zingerman " ::: __clobber_all);
115*edff37b2SEduard Zingerman }
116*edff37b2SEduard Zingerman
117*edff37b2SEduard Zingerman SEC("socket")
118*edff37b2SEduard Zingerman __description("PTR_TO_STACK check high 2")
119*edff37b2SEduard Zingerman __success __success_unpriv __retval(42)
to_stack_check_high_2(void)120*edff37b2SEduard Zingerman __naked void to_stack_check_high_2(void)
121*edff37b2SEduard Zingerman {
122*edff37b2SEduard Zingerman asm volatile (" \
123*edff37b2SEduard Zingerman r1 = r10; \
124*edff37b2SEduard Zingerman r0 = 42; \
125*edff37b2SEduard Zingerman *(u8*)(r1 - 1) = r0; \
126*edff37b2SEduard Zingerman r0 = *(u8*)(r1 - 1); \
127*edff37b2SEduard Zingerman exit; \
128*edff37b2SEduard Zingerman " ::: __clobber_all);
129*edff37b2SEduard Zingerman }
130*edff37b2SEduard Zingerman
131*edff37b2SEduard Zingerman SEC("socket")
132*edff37b2SEduard Zingerman __description("PTR_TO_STACK check high 3")
133*edff37b2SEduard Zingerman __success __failure_unpriv
134*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
135*edff37b2SEduard Zingerman __retval(42)
to_stack_check_high_3(void)136*edff37b2SEduard Zingerman __naked void to_stack_check_high_3(void)
137*edff37b2SEduard Zingerman {
138*edff37b2SEduard Zingerman asm volatile (" \
139*edff37b2SEduard Zingerman r1 = r10; \
140*edff37b2SEduard Zingerman r1 += 0; \
141*edff37b2SEduard Zingerman r0 = 42; \
142*edff37b2SEduard Zingerman *(u8*)(r1 - 1) = r0; \
143*edff37b2SEduard Zingerman r0 = *(u8*)(r1 - 1); \
144*edff37b2SEduard Zingerman exit; \
145*edff37b2SEduard Zingerman " ::: __clobber_all);
146*edff37b2SEduard Zingerman }
147*edff37b2SEduard Zingerman
148*edff37b2SEduard Zingerman SEC("socket")
149*edff37b2SEduard Zingerman __description("PTR_TO_STACK check high 4")
150*edff37b2SEduard Zingerman __failure __msg("invalid write to stack R1 off=0 size=1")
151*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_high_4(void)152*edff37b2SEduard Zingerman __naked void to_stack_check_high_4(void)
153*edff37b2SEduard Zingerman {
154*edff37b2SEduard Zingerman asm volatile (" \
155*edff37b2SEduard Zingerman r1 = r10; \
156*edff37b2SEduard Zingerman r1 += 0; \
157*edff37b2SEduard Zingerman r0 = 42; \
158*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
159*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
160*edff37b2SEduard Zingerman exit; \
161*edff37b2SEduard Zingerman " ::: __clobber_all);
162*edff37b2SEduard Zingerman }
163*edff37b2SEduard Zingerman
164*edff37b2SEduard Zingerman SEC("socket")
165*edff37b2SEduard Zingerman __description("PTR_TO_STACK check high 5")
166*edff37b2SEduard Zingerman __failure __msg("invalid write to stack R1")
167*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_high_5(void)168*edff37b2SEduard Zingerman __naked void to_stack_check_high_5(void)
169*edff37b2SEduard Zingerman {
170*edff37b2SEduard Zingerman asm volatile (" \
171*edff37b2SEduard Zingerman r1 = r10; \
172*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
173*edff37b2SEduard Zingerman r0 = 42; \
174*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
175*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
176*edff37b2SEduard Zingerman exit; \
177*edff37b2SEduard Zingerman " :
178*edff37b2SEduard Zingerman : __imm_const(__imm_0, (1 << 29) - 1)
179*edff37b2SEduard Zingerman : __clobber_all);
180*edff37b2SEduard Zingerman }
181*edff37b2SEduard Zingerman
182*edff37b2SEduard Zingerman SEC("socket")
183*edff37b2SEduard Zingerman __description("PTR_TO_STACK check high 6")
184*edff37b2SEduard Zingerman __failure __msg("invalid write to stack")
185*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_high_6(void)186*edff37b2SEduard Zingerman __naked void to_stack_check_high_6(void)
187*edff37b2SEduard Zingerman {
188*edff37b2SEduard Zingerman asm volatile (" \
189*edff37b2SEduard Zingerman r1 = r10; \
190*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
191*edff37b2SEduard Zingerman r0 = 42; \
192*edff37b2SEduard Zingerman *(u8*)(r1 + %[shrt_max]) = r0; \
193*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + %[shrt_max]); \
194*edff37b2SEduard Zingerman exit; \
195*edff37b2SEduard Zingerman " :
196*edff37b2SEduard Zingerman : __imm_const(__imm_0, (1 << 29) - 1),
197*edff37b2SEduard Zingerman __imm_const(shrt_max, SHRT_MAX)
198*edff37b2SEduard Zingerman : __clobber_all);
199*edff37b2SEduard Zingerman }
200*edff37b2SEduard Zingerman
201*edff37b2SEduard Zingerman SEC("socket")
202*edff37b2SEduard Zingerman __description("PTR_TO_STACK check high 7")
203*edff37b2SEduard Zingerman __failure __msg("fp pointer offset")
204*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_high_7(void)205*edff37b2SEduard Zingerman __naked void to_stack_check_high_7(void)
206*edff37b2SEduard Zingerman {
207*edff37b2SEduard Zingerman asm volatile (" \
208*edff37b2SEduard Zingerman r1 = r10; \
209*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
210*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
211*edff37b2SEduard Zingerman r0 = 42; \
212*edff37b2SEduard Zingerman *(u8*)(r1 + %[shrt_max]) = r0; \
213*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + %[shrt_max]); \
214*edff37b2SEduard Zingerman exit; \
215*edff37b2SEduard Zingerman " :
216*edff37b2SEduard Zingerman : __imm_const(__imm_0, (1 << 29) - 1),
217*edff37b2SEduard Zingerman __imm_const(shrt_max, SHRT_MAX)
218*edff37b2SEduard Zingerman : __clobber_all);
219*edff37b2SEduard Zingerman }
220*edff37b2SEduard Zingerman
221*edff37b2SEduard Zingerman SEC("socket")
222*edff37b2SEduard Zingerman __description("PTR_TO_STACK check low 1")
223*edff37b2SEduard Zingerman __success __success_unpriv __retval(42)
to_stack_check_low_1(void)224*edff37b2SEduard Zingerman __naked void to_stack_check_low_1(void)
225*edff37b2SEduard Zingerman {
226*edff37b2SEduard Zingerman asm volatile (" \
227*edff37b2SEduard Zingerman r1 = r10; \
228*edff37b2SEduard Zingerman r1 += -512; \
229*edff37b2SEduard Zingerman r0 = 42; \
230*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
231*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
232*edff37b2SEduard Zingerman exit; \
233*edff37b2SEduard Zingerman " ::: __clobber_all);
234*edff37b2SEduard Zingerman }
235*edff37b2SEduard Zingerman
236*edff37b2SEduard Zingerman SEC("socket")
237*edff37b2SEduard Zingerman __description("PTR_TO_STACK check low 2")
238*edff37b2SEduard Zingerman __success __failure_unpriv
239*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
240*edff37b2SEduard Zingerman __retval(42)
to_stack_check_low_2(void)241*edff37b2SEduard Zingerman __naked void to_stack_check_low_2(void)
242*edff37b2SEduard Zingerman {
243*edff37b2SEduard Zingerman asm volatile (" \
244*edff37b2SEduard Zingerman r1 = r10; \
245*edff37b2SEduard Zingerman r1 += -513; \
246*edff37b2SEduard Zingerman r0 = 42; \
247*edff37b2SEduard Zingerman *(u8*)(r1 + 1) = r0; \
248*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 1); \
249*edff37b2SEduard Zingerman exit; \
250*edff37b2SEduard Zingerman " ::: __clobber_all);
251*edff37b2SEduard Zingerman }
252*edff37b2SEduard Zingerman
253*edff37b2SEduard Zingerman SEC("socket")
254*edff37b2SEduard Zingerman __description("PTR_TO_STACK check low 3")
255*edff37b2SEduard Zingerman __failure __msg("invalid write to stack R1 off=-513 size=1")
256*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_low_3(void)257*edff37b2SEduard Zingerman __naked void to_stack_check_low_3(void)
258*edff37b2SEduard Zingerman {
259*edff37b2SEduard Zingerman asm volatile (" \
260*edff37b2SEduard Zingerman r1 = r10; \
261*edff37b2SEduard Zingerman r1 += -513; \
262*edff37b2SEduard Zingerman r0 = 42; \
263*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
264*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
265*edff37b2SEduard Zingerman exit; \
266*edff37b2SEduard Zingerman " ::: __clobber_all);
267*edff37b2SEduard Zingerman }
268*edff37b2SEduard Zingerman
269*edff37b2SEduard Zingerman SEC("socket")
270*edff37b2SEduard Zingerman __description("PTR_TO_STACK check low 4")
271*edff37b2SEduard Zingerman __failure __msg("math between fp pointer")
272*edff37b2SEduard Zingerman __failure_unpriv
to_stack_check_low_4(void)273*edff37b2SEduard Zingerman __naked void to_stack_check_low_4(void)
274*edff37b2SEduard Zingerman {
275*edff37b2SEduard Zingerman asm volatile (" \
276*edff37b2SEduard Zingerman r1 = r10; \
277*edff37b2SEduard Zingerman r1 += %[int_min]; \
278*edff37b2SEduard Zingerman r0 = 42; \
279*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
280*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
281*edff37b2SEduard Zingerman exit; \
282*edff37b2SEduard Zingerman " :
283*edff37b2SEduard Zingerman : __imm_const(int_min, INT_MIN)
284*edff37b2SEduard Zingerman : __clobber_all);
285*edff37b2SEduard Zingerman }
286*edff37b2SEduard Zingerman
287*edff37b2SEduard Zingerman SEC("socket")
288*edff37b2SEduard Zingerman __description("PTR_TO_STACK check low 5")
289*edff37b2SEduard Zingerman __failure __msg("invalid write to stack")
290*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_low_5(void)291*edff37b2SEduard Zingerman __naked void to_stack_check_low_5(void)
292*edff37b2SEduard Zingerman {
293*edff37b2SEduard Zingerman asm volatile (" \
294*edff37b2SEduard Zingerman r1 = r10; \
295*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
296*edff37b2SEduard Zingerman r0 = 42; \
297*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
298*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
299*edff37b2SEduard Zingerman exit; \
300*edff37b2SEduard Zingerman " :
301*edff37b2SEduard Zingerman : __imm_const(__imm_0, -((1 << 29) - 1))
302*edff37b2SEduard Zingerman : __clobber_all);
303*edff37b2SEduard Zingerman }
304*edff37b2SEduard Zingerman
305*edff37b2SEduard Zingerman SEC("socket")
306*edff37b2SEduard Zingerman __description("PTR_TO_STACK check low 6")
307*edff37b2SEduard Zingerman __failure __msg("invalid write to stack")
308*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_low_6(void)309*edff37b2SEduard Zingerman __naked void to_stack_check_low_6(void)
310*edff37b2SEduard Zingerman {
311*edff37b2SEduard Zingerman asm volatile (" \
312*edff37b2SEduard Zingerman r1 = r10; \
313*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
314*edff37b2SEduard Zingerman r0 = 42; \
315*edff37b2SEduard Zingerman *(u8*)(r1 %[shrt_min]) = r0; \
316*edff37b2SEduard Zingerman r0 = *(u8*)(r1 %[shrt_min]); \
317*edff37b2SEduard Zingerman exit; \
318*edff37b2SEduard Zingerman " :
319*edff37b2SEduard Zingerman : __imm_const(__imm_0, -((1 << 29) - 1)),
320*edff37b2SEduard Zingerman __imm_const(shrt_min, SHRT_MIN)
321*edff37b2SEduard Zingerman : __clobber_all);
322*edff37b2SEduard Zingerman }
323*edff37b2SEduard Zingerman
324*edff37b2SEduard Zingerman SEC("socket")
325*edff37b2SEduard Zingerman __description("PTR_TO_STACK check low 7")
326*edff37b2SEduard Zingerman __failure __msg("fp pointer offset")
327*edff37b2SEduard Zingerman __msg_unpriv("R1 stack pointer arithmetic goes out of range")
to_stack_check_low_7(void)328*edff37b2SEduard Zingerman __naked void to_stack_check_low_7(void)
329*edff37b2SEduard Zingerman {
330*edff37b2SEduard Zingerman asm volatile (" \
331*edff37b2SEduard Zingerman r1 = r10; \
332*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
333*edff37b2SEduard Zingerman r1 += %[__imm_0]; \
334*edff37b2SEduard Zingerman r0 = 42; \
335*edff37b2SEduard Zingerman *(u8*)(r1 %[shrt_min]) = r0; \
336*edff37b2SEduard Zingerman r0 = *(u8*)(r1 %[shrt_min]); \
337*edff37b2SEduard Zingerman exit; \
338*edff37b2SEduard Zingerman " :
339*edff37b2SEduard Zingerman : __imm_const(__imm_0, -((1 << 29) - 1)),
340*edff37b2SEduard Zingerman __imm_const(shrt_min, SHRT_MIN)
341*edff37b2SEduard Zingerman : __clobber_all);
342*edff37b2SEduard Zingerman }
343*edff37b2SEduard Zingerman
344*edff37b2SEduard Zingerman SEC("socket")
345*edff37b2SEduard Zingerman __description("PTR_TO_STACK mixed reg/k, 1")
346*edff37b2SEduard Zingerman __success __success_unpriv __retval(42)
stack_mixed_reg_k_1(void)347*edff37b2SEduard Zingerman __naked void stack_mixed_reg_k_1(void)
348*edff37b2SEduard Zingerman {
349*edff37b2SEduard Zingerman asm volatile (" \
350*edff37b2SEduard Zingerman r1 = r10; \
351*edff37b2SEduard Zingerman r1 += -3; \
352*edff37b2SEduard Zingerman r2 = -3; \
353*edff37b2SEduard Zingerman r1 += r2; \
354*edff37b2SEduard Zingerman r0 = 42; \
355*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
356*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
357*edff37b2SEduard Zingerman exit; \
358*edff37b2SEduard Zingerman " ::: __clobber_all);
359*edff37b2SEduard Zingerman }
360*edff37b2SEduard Zingerman
361*edff37b2SEduard Zingerman SEC("socket")
362*edff37b2SEduard Zingerman __description("PTR_TO_STACK mixed reg/k, 2")
363*edff37b2SEduard Zingerman __success __success_unpriv __retval(42)
stack_mixed_reg_k_2(void)364*edff37b2SEduard Zingerman __naked void stack_mixed_reg_k_2(void)
365*edff37b2SEduard Zingerman {
366*edff37b2SEduard Zingerman asm volatile (" \
367*edff37b2SEduard Zingerman r0 = 0; \
368*edff37b2SEduard Zingerman *(u64*)(r10 - 8) = r0; \
369*edff37b2SEduard Zingerman r0 = 0; \
370*edff37b2SEduard Zingerman *(u64*)(r10 - 16) = r0; \
371*edff37b2SEduard Zingerman r1 = r10; \
372*edff37b2SEduard Zingerman r1 += -3; \
373*edff37b2SEduard Zingerman r2 = -3; \
374*edff37b2SEduard Zingerman r1 += r2; \
375*edff37b2SEduard Zingerman r0 = 42; \
376*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
377*edff37b2SEduard Zingerman r5 = r10; \
378*edff37b2SEduard Zingerman r0 = *(u8*)(r5 - 6); \
379*edff37b2SEduard Zingerman exit; \
380*edff37b2SEduard Zingerman " ::: __clobber_all);
381*edff37b2SEduard Zingerman }
382*edff37b2SEduard Zingerman
383*edff37b2SEduard Zingerman SEC("socket")
384*edff37b2SEduard Zingerman __description("PTR_TO_STACK mixed reg/k, 3")
385*edff37b2SEduard Zingerman __success __success_unpriv __retval(-3)
stack_mixed_reg_k_3(void)386*edff37b2SEduard Zingerman __naked void stack_mixed_reg_k_3(void)
387*edff37b2SEduard Zingerman {
388*edff37b2SEduard Zingerman asm volatile (" \
389*edff37b2SEduard Zingerman r1 = r10; \
390*edff37b2SEduard Zingerman r1 += -3; \
391*edff37b2SEduard Zingerman r2 = -3; \
392*edff37b2SEduard Zingerman r1 += r2; \
393*edff37b2SEduard Zingerman r0 = 42; \
394*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
395*edff37b2SEduard Zingerman r0 = r2; \
396*edff37b2SEduard Zingerman exit; \
397*edff37b2SEduard Zingerman " ::: __clobber_all);
398*edff37b2SEduard Zingerman }
399*edff37b2SEduard Zingerman
400*edff37b2SEduard Zingerman SEC("socket")
401*edff37b2SEduard Zingerman __description("PTR_TO_STACK reg")
402*edff37b2SEduard Zingerman __success __success_unpriv __retval(42)
ptr_to_stack_reg(void)403*edff37b2SEduard Zingerman __naked void ptr_to_stack_reg(void)
404*edff37b2SEduard Zingerman {
405*edff37b2SEduard Zingerman asm volatile (" \
406*edff37b2SEduard Zingerman r1 = r10; \
407*edff37b2SEduard Zingerman r2 = -3; \
408*edff37b2SEduard Zingerman r1 += r2; \
409*edff37b2SEduard Zingerman r0 = 42; \
410*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r0; \
411*edff37b2SEduard Zingerman r0 = *(u8*)(r1 + 0); \
412*edff37b2SEduard Zingerman exit; \
413*edff37b2SEduard Zingerman " ::: __clobber_all);
414*edff37b2SEduard Zingerman }
415*edff37b2SEduard Zingerman
416*edff37b2SEduard Zingerman SEC("socket")
417*edff37b2SEduard Zingerman __description("stack pointer arithmetic")
418*edff37b2SEduard Zingerman __success __success_unpriv __retval(0)
stack_pointer_arithmetic(void)419*edff37b2SEduard Zingerman __naked void stack_pointer_arithmetic(void)
420*edff37b2SEduard Zingerman {
421*edff37b2SEduard Zingerman asm volatile (" \
422*edff37b2SEduard Zingerman r1 = 4; \
423*edff37b2SEduard Zingerman goto l0_%=; \
424*edff37b2SEduard Zingerman l0_%=: r7 = r10; \
425*edff37b2SEduard Zingerman r7 += -10; \
426*edff37b2SEduard Zingerman r7 += -10; \
427*edff37b2SEduard Zingerman r2 = r7; \
428*edff37b2SEduard Zingerman r2 += r1; \
429*edff37b2SEduard Zingerman r0 = 0; \
430*edff37b2SEduard Zingerman *(u32*)(r2 + 4) = r0; \
431*edff37b2SEduard Zingerman r2 = r7; \
432*edff37b2SEduard Zingerman r2 += 8; \
433*edff37b2SEduard Zingerman r0 = 0; \
434*edff37b2SEduard Zingerman *(u32*)(r2 + 4) = r0; \
435*edff37b2SEduard Zingerman r0 = 0; \
436*edff37b2SEduard Zingerman exit; \
437*edff37b2SEduard Zingerman " ::: __clobber_all);
438*edff37b2SEduard Zingerman }
439*edff37b2SEduard Zingerman
440*edff37b2SEduard Zingerman SEC("tc")
441*edff37b2SEduard Zingerman __description("store PTR_TO_STACK in R10 to array map using BPF_B")
442*edff37b2SEduard Zingerman __success __retval(42)
array_map_using_bpf_b(void)443*edff37b2SEduard Zingerman __naked void array_map_using_bpf_b(void)
444*edff37b2SEduard Zingerman {
445*edff37b2SEduard Zingerman asm volatile (" \
446*edff37b2SEduard Zingerman /* Load pointer to map. */ \
447*edff37b2SEduard Zingerman r2 = r10; \
448*edff37b2SEduard Zingerman r2 += -8; \
449*edff37b2SEduard Zingerman r1 = 0; \
450*edff37b2SEduard Zingerman *(u64*)(r2 + 0) = r1; \
451*edff37b2SEduard Zingerman r1 = %[map_array_48b] ll; \
452*edff37b2SEduard Zingerman call %[bpf_map_lookup_elem]; \
453*edff37b2SEduard Zingerman if r0 != 0 goto l0_%=; \
454*edff37b2SEduard Zingerman r0 = 2; \
455*edff37b2SEduard Zingerman exit; \
456*edff37b2SEduard Zingerman l0_%=: r1 = r0; \
457*edff37b2SEduard Zingerman /* Copy R10 to R9. */ \
458*edff37b2SEduard Zingerman r9 = r10; \
459*edff37b2SEduard Zingerman /* Pollute other registers with unaligned values. */\
460*edff37b2SEduard Zingerman r2 = -1; \
461*edff37b2SEduard Zingerman r3 = -1; \
462*edff37b2SEduard Zingerman r4 = -1; \
463*edff37b2SEduard Zingerman r5 = -1; \
464*edff37b2SEduard Zingerman r6 = -1; \
465*edff37b2SEduard Zingerman r7 = -1; \
466*edff37b2SEduard Zingerman r8 = -1; \
467*edff37b2SEduard Zingerman /* Store both R9 and R10 with BPF_B and read back. */\
468*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r10; \
469*edff37b2SEduard Zingerman r2 = *(u8*)(r1 + 0); \
470*edff37b2SEduard Zingerman *(u8*)(r1 + 0) = r9; \
471*edff37b2SEduard Zingerman r3 = *(u8*)(r1 + 0); \
472*edff37b2SEduard Zingerman /* Should read back as same value. */ \
473*edff37b2SEduard Zingerman if r2 == r3 goto l1_%=; \
474*edff37b2SEduard Zingerman r0 = 1; \
475*edff37b2SEduard Zingerman exit; \
476*edff37b2SEduard Zingerman l1_%=: r0 = 42; \
477*edff37b2SEduard Zingerman exit; \
478*edff37b2SEduard Zingerman " :
479*edff37b2SEduard Zingerman : __imm(bpf_map_lookup_elem),
480*edff37b2SEduard Zingerman __imm_addr(map_array_48b)
481*edff37b2SEduard Zingerman : __clobber_all);
482*edff37b2SEduard Zingerman }
483*edff37b2SEduard Zingerman
484*edff37b2SEduard Zingerman char _license[] SEC("license") = "GPL";
485