Linux Audio

Check our new training course

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