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