xref: /linux/tools/testing/selftests/bpf/progs/verifier_basic_stack.c (revision 06d07429858317ded2db7986113a9e0129cd599b)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/basic_stack.c */
3 
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 struct {
9 	__uint(type, BPF_MAP_TYPE_HASH);
10 	__uint(max_entries, 1);
11 	__type(key, long long);
12 	__type(value, long long);
13 } map_hash_8b SEC(".maps");
14 
15 SEC("socket")
16 __description("stack out of bounds")
17 __failure __msg("invalid write to stack")
18 __failure_unpriv
stack_out_of_bounds(void)19 __naked void stack_out_of_bounds(void)
20 {
21 	asm volatile ("					\
22 	r1 = 0;						\
23 	*(u64*)(r10 + 8) = r1;				\
24 	exit;						\
25 "	::: __clobber_all);
26 }
27 
28 SEC("socket")
29 __description("uninitialized stack1")
30 __success __log_level(4) __msg("stack depth 8")
31 __failure_unpriv __msg_unpriv("invalid indirect read from stack")
uninitialized_stack1(void)32 __naked void uninitialized_stack1(void)
33 {
34 	asm volatile ("					\
35 	r2 = r10;					\
36 	r2 += -8;					\
37 	r1 = %[map_hash_8b] ll;				\
38 	call %[bpf_map_lookup_elem];			\
39 	exit;						\
40 "	:
41 	: __imm(bpf_map_lookup_elem),
42 	  __imm_addr(map_hash_8b)
43 	: __clobber_all);
44 }
45 
46 SEC("socket")
47 __description("uninitialized stack2")
48 __success __log_level(4) __msg("stack depth 8")
49 __failure_unpriv __msg_unpriv("invalid read from stack")
uninitialized_stack2(void)50 __naked void uninitialized_stack2(void)
51 {
52 	asm volatile ("					\
53 	r2 = r10;					\
54 	r0 = *(u64*)(r2 - 8);				\
55 	exit;						\
56 "	::: __clobber_all);
57 }
58 
59 SEC("socket")
60 __description("invalid fp arithmetic")
61 __failure __msg("R1 subtraction from stack pointer")
62 __failure_unpriv
invalid_fp_arithmetic(void)63 __naked void invalid_fp_arithmetic(void)
64 {
65 	/* If this gets ever changed, make sure JITs can deal with it. */
66 	asm volatile ("					\
67 	r0 = 0;						\
68 	r1 = r10;					\
69 	r1 -= 8;					\
70 	*(u64*)(r1 + 0) = r0;				\
71 	exit;						\
72 "	::: __clobber_all);
73 }
74 
75 SEC("socket")
76 __description("non-invalid fp arithmetic")
77 __success __success_unpriv __retval(0)
non_invalid_fp_arithmetic(void)78 __naked void non_invalid_fp_arithmetic(void)
79 {
80 	asm volatile ("					\
81 	r0 = 0;						\
82 	*(u64*)(r10 - 8) = r0;				\
83 	exit;						\
84 "	::: __clobber_all);
85 }
86 
87 SEC("socket")
88 __description("misaligned read from stack")
89 __failure __msg("misaligned stack access")
90 __failure_unpriv
misaligned_read_from_stack(void)91 __naked void misaligned_read_from_stack(void)
92 {
93 	asm volatile ("					\
94 	r2 = r10;					\
95 	r0 = *(u64*)(r2 - 4);				\
96 	exit;						\
97 "	::: __clobber_all);
98 }
99 
100 char _license[] SEC("license") = "GPL";
101