10ccbe495SEduard Zingerman // SPDX-License-Identifier: GPL-2.0
20ccbe495SEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/basic_stack.c */
30ccbe495SEduard Zingerman 
40ccbe495SEduard Zingerman #include <linux/bpf.h>
50ccbe495SEduard Zingerman #include <bpf/bpf_helpers.h>
60ccbe495SEduard Zingerman #include "bpf_misc.h"
70ccbe495SEduard Zingerman 
80ccbe495SEduard Zingerman struct {
90ccbe495SEduard Zingerman 	__uint(type, BPF_MAP_TYPE_HASH);
100ccbe495SEduard Zingerman 	__uint(max_entries, 1);
110ccbe495SEduard Zingerman 	__type(key, long long);
120ccbe495SEduard Zingerman 	__type(value, long long);
130ccbe495SEduard Zingerman } map_hash_8b SEC(".maps");
140ccbe495SEduard Zingerman 
150ccbe495SEduard Zingerman SEC("socket")
160ccbe495SEduard Zingerman __description("stack out of bounds")
170ccbe495SEduard Zingerman __failure __msg("invalid write to stack")
180ccbe495SEduard Zingerman __failure_unpriv
stack_out_of_bounds(void)190ccbe495SEduard Zingerman __naked void stack_out_of_bounds(void)
200ccbe495SEduard Zingerman {
210ccbe495SEduard Zingerman 	asm volatile ("					\
220ccbe495SEduard Zingerman 	r1 = 0;						\
230ccbe495SEduard Zingerman 	*(u64*)(r10 + 8) = r1;				\
240ccbe495SEduard Zingerman 	exit;						\
250ccbe495SEduard Zingerman "	::: __clobber_all);
260ccbe495SEduard Zingerman }
270ccbe495SEduard Zingerman 
280ccbe495SEduard Zingerman SEC("socket")
290ccbe495SEduard Zingerman __description("uninitialized stack1")
30*0954982dSAndrei Matei __success __log_level(4) __msg("stack depth 8")
31*0954982dSAndrei Matei __failure_unpriv __msg_unpriv("invalid indirect read from stack")
uninitialized_stack1(void)320ccbe495SEduard Zingerman __naked void uninitialized_stack1(void)
330ccbe495SEduard Zingerman {
340ccbe495SEduard Zingerman 	asm volatile ("					\
350ccbe495SEduard Zingerman 	r2 = r10;					\
360ccbe495SEduard Zingerman 	r2 += -8;					\
370ccbe495SEduard Zingerman 	r1 = %[map_hash_8b] ll;				\
380ccbe495SEduard Zingerman 	call %[bpf_map_lookup_elem];			\
390ccbe495SEduard Zingerman 	exit;						\
400ccbe495SEduard Zingerman "	:
410ccbe495SEduard Zingerman 	: __imm(bpf_map_lookup_elem),
420ccbe495SEduard Zingerman 	  __imm_addr(map_hash_8b)
430ccbe495SEduard Zingerman 	: __clobber_all);
440ccbe495SEduard Zingerman }
450ccbe495SEduard Zingerman 
460ccbe495SEduard Zingerman SEC("socket")
470ccbe495SEduard Zingerman __description("uninitialized stack2")
48*0954982dSAndrei Matei __success __log_level(4) __msg("stack depth 8")
49*0954982dSAndrei Matei __failure_unpriv __msg_unpriv("invalid read from stack")
uninitialized_stack2(void)500ccbe495SEduard Zingerman __naked void uninitialized_stack2(void)
510ccbe495SEduard Zingerman {
520ccbe495SEduard Zingerman 	asm volatile ("					\
530ccbe495SEduard Zingerman 	r2 = r10;					\
540ccbe495SEduard Zingerman 	r0 = *(u64*)(r2 - 8);				\
550ccbe495SEduard Zingerman 	exit;						\
560ccbe495SEduard Zingerman "	::: __clobber_all);
570ccbe495SEduard Zingerman }
580ccbe495SEduard Zingerman 
590ccbe495SEduard Zingerman SEC("socket")
600ccbe495SEduard Zingerman __description("invalid fp arithmetic")
610ccbe495SEduard Zingerman __failure __msg("R1 subtraction from stack pointer")
620ccbe495SEduard Zingerman __failure_unpriv
invalid_fp_arithmetic(void)630ccbe495SEduard Zingerman __naked void invalid_fp_arithmetic(void)
640ccbe495SEduard Zingerman {
650ccbe495SEduard Zingerman 	/* If this gets ever changed, make sure JITs can deal with it. */
660ccbe495SEduard Zingerman 	asm volatile ("					\
670ccbe495SEduard Zingerman 	r0 = 0;						\
680ccbe495SEduard Zingerman 	r1 = r10;					\
690ccbe495SEduard Zingerman 	r1 -= 8;					\
700ccbe495SEduard Zingerman 	*(u64*)(r1 + 0) = r0;				\
710ccbe495SEduard Zingerman 	exit;						\
720ccbe495SEduard Zingerman "	::: __clobber_all);
730ccbe495SEduard Zingerman }
740ccbe495SEduard Zingerman 
750ccbe495SEduard Zingerman SEC("socket")
760ccbe495SEduard Zingerman __description("non-invalid fp arithmetic")
770ccbe495SEduard Zingerman __success __success_unpriv __retval(0)
non_invalid_fp_arithmetic(void)780ccbe495SEduard Zingerman __naked void non_invalid_fp_arithmetic(void)
790ccbe495SEduard Zingerman {
800ccbe495SEduard Zingerman 	asm volatile ("					\
810ccbe495SEduard Zingerman 	r0 = 0;						\
820ccbe495SEduard Zingerman 	*(u64*)(r10 - 8) = r0;				\
830ccbe495SEduard Zingerman 	exit;						\
840ccbe495SEduard Zingerman "	::: __clobber_all);
850ccbe495SEduard Zingerman }
860ccbe495SEduard Zingerman 
870ccbe495SEduard Zingerman SEC("socket")
880ccbe495SEduard Zingerman __description("misaligned read from stack")
890ccbe495SEduard Zingerman __failure __msg("misaligned stack access")
900ccbe495SEduard Zingerman __failure_unpriv
misaligned_read_from_stack(void)910ccbe495SEduard Zingerman __naked void misaligned_read_from_stack(void)
920ccbe495SEduard Zingerman {
930ccbe495SEduard Zingerman 	asm volatile ("					\
940ccbe495SEduard Zingerman 	r2 = r10;					\
950ccbe495SEduard Zingerman 	r0 = *(u64*)(r2 - 4);				\
960ccbe495SEduard Zingerman 	exit;						\
970ccbe495SEduard Zingerman "	::: __clobber_all);
980ccbe495SEduard Zingerman }
990ccbe495SEduard Zingerman 
1000ccbe495SEduard Zingerman char _license[] SEC("license") = "GPL";
101