xref: /linux/tools/testing/selftests/bpf/progs/verifier_private_stack.c (revision 25768de50b1f2dbb6ea44bd5148a87fe2c9c3688)
1*f4b295abSYonghong Song // SPDX-License-Identifier: GPL-2.0
2*f4b295abSYonghong Song 
3*f4b295abSYonghong Song #include <vmlinux.h>
4*f4b295abSYonghong Song #include <bpf/bpf_helpers.h>
5*f4b295abSYonghong Song #include "bpf_misc.h"
6*f4b295abSYonghong Song #include "bpf_experimental.h"
7*f4b295abSYonghong Song 
8*f4b295abSYonghong Song /* From include/linux/filter.h */
9*f4b295abSYonghong Song #define MAX_BPF_STACK    512
10*f4b295abSYonghong Song 
11*f4b295abSYonghong Song #if defined(__TARGET_ARCH_x86)
12*f4b295abSYonghong Song 
13*f4b295abSYonghong Song struct elem {
14*f4b295abSYonghong Song 	struct bpf_timer t;
15*f4b295abSYonghong Song 	char pad[256];
16*f4b295abSYonghong Song };
17*f4b295abSYonghong Song 
18*f4b295abSYonghong Song struct {
19*f4b295abSYonghong Song 	__uint(type, BPF_MAP_TYPE_ARRAY);
20*f4b295abSYonghong Song 	__uint(max_entries, 1);
21*f4b295abSYonghong Song 	__type(key, int);
22*f4b295abSYonghong Song 	__type(value, struct elem);
23*f4b295abSYonghong Song } array SEC(".maps");
24*f4b295abSYonghong Song 
25*f4b295abSYonghong Song SEC("kprobe")
26*f4b295abSYonghong Song __description("Private stack, single prog")
27*f4b295abSYonghong Song __success
28*f4b295abSYonghong Song __arch_x86_64
29*f4b295abSYonghong Song __jited("	movabsq	$0x{{.*}}, %r9")
30*f4b295abSYonghong Song __jited("	addq	%gs:0x{{.*}}, %r9")
31*f4b295abSYonghong Song __jited("	movl	$0x2a, %edi")
32*f4b295abSYonghong Song __jited("	movq	%rdi, -0x100(%r9)")
33*f4b295abSYonghong Song __naked void private_stack_single_prog(void)
34*f4b295abSYonghong Song {
35*f4b295abSYonghong Song 	asm volatile ("			\
36*f4b295abSYonghong Song 	r1 = 42;			\
37*f4b295abSYonghong Song 	*(u64 *)(r10 - 256) = r1;	\
38*f4b295abSYonghong Song 	r0 = 0;				\
39*f4b295abSYonghong Song 	exit;				\
40*f4b295abSYonghong Song "	::: __clobber_all);
41*f4b295abSYonghong Song }
42*f4b295abSYonghong Song 
43*f4b295abSYonghong Song SEC("raw_tp")
44*f4b295abSYonghong Song __description("No private stack")
45*f4b295abSYonghong Song __success
46*f4b295abSYonghong Song __arch_x86_64
47*f4b295abSYonghong Song __jited("	subq	$0x8, %rsp")
48*f4b295abSYonghong Song __naked void no_private_stack_nested(void)
49*f4b295abSYonghong Song {
50*f4b295abSYonghong Song 	asm volatile ("			\
51*f4b295abSYonghong Song 	r1 = 42;			\
52*f4b295abSYonghong Song 	*(u64 *)(r10 - 8) = r1;		\
53*f4b295abSYonghong Song 	r0 = 0;				\
54*f4b295abSYonghong Song 	exit;				\
55*f4b295abSYonghong Song "	::: __clobber_all);
56*f4b295abSYonghong Song }
57*f4b295abSYonghong Song 
58*f4b295abSYonghong Song __used
59*f4b295abSYonghong Song __naked static void cumulative_stack_depth_subprog(void)
60*f4b295abSYonghong Song {
61*f4b295abSYonghong Song 	asm volatile ("				\
62*f4b295abSYonghong Song 	r1 = 41;				\
63*f4b295abSYonghong Song 	*(u64 *)(r10 - 32) = r1;		\
64*f4b295abSYonghong Song 	call %[bpf_get_smp_processor_id];	\
65*f4b295abSYonghong Song 	exit;					\
66*f4b295abSYonghong Song "	:
67*f4b295abSYonghong Song 	: __imm(bpf_get_smp_processor_id)
68*f4b295abSYonghong Song 	: __clobber_all);
69*f4b295abSYonghong Song }
70*f4b295abSYonghong Song 
71*f4b295abSYonghong Song SEC("kprobe")
72*f4b295abSYonghong Song __description("Private stack, subtree > MAX_BPF_STACK")
73*f4b295abSYonghong Song __success
74*f4b295abSYonghong Song __arch_x86_64
75*f4b295abSYonghong Song /* private stack fp for the main prog */
76*f4b295abSYonghong Song __jited("	movabsq	$0x{{.*}}, %r9")
77*f4b295abSYonghong Song __jited("	addq	%gs:0x{{.*}}, %r9")
78*f4b295abSYonghong Song __jited("	movl	$0x2a, %edi")
79*f4b295abSYonghong Song __jited("	movq	%rdi, -0x200(%r9)")
80*f4b295abSYonghong Song __jited("	pushq	%r9")
81*f4b295abSYonghong Song __jited("	callq	0x{{.*}}")
82*f4b295abSYonghong Song __jited("	popq	%r9")
83*f4b295abSYonghong Song __jited("	xorl	%eax, %eax")
84*f4b295abSYonghong Song __naked void private_stack_nested_1(void)
85*f4b295abSYonghong Song {
86*f4b295abSYonghong Song 	asm volatile ("				\
87*f4b295abSYonghong Song 	r1 = 42;				\
88*f4b295abSYonghong Song 	*(u64 *)(r10 - %[max_bpf_stack]) = r1;	\
89*f4b295abSYonghong Song 	call cumulative_stack_depth_subprog;	\
90*f4b295abSYonghong Song 	r0 = 0;					\
91*f4b295abSYonghong Song 	exit;					\
92*f4b295abSYonghong Song "	:
93*f4b295abSYonghong Song 	: __imm_const(max_bpf_stack, MAX_BPF_STACK)
94*f4b295abSYonghong Song 	: __clobber_all);
95*f4b295abSYonghong Song }
96*f4b295abSYonghong Song 
97*f4b295abSYonghong Song __naked __noinline __used
98*f4b295abSYonghong Song static unsigned long loop_callback(void)
99*f4b295abSYonghong Song {
100*f4b295abSYonghong Song 	asm volatile ("				\
101*f4b295abSYonghong Song 	call %[bpf_get_prandom_u32];		\
102*f4b295abSYonghong Song 	r1 = 42;				\
103*f4b295abSYonghong Song 	*(u64 *)(r10 - 512) = r1;		\
104*f4b295abSYonghong Song 	call cumulative_stack_depth_subprog;	\
105*f4b295abSYonghong Song 	r0 = 0;					\
106*f4b295abSYonghong Song 	exit;					\
107*f4b295abSYonghong Song "	:
108*f4b295abSYonghong Song 	: __imm(bpf_get_prandom_u32)
109*f4b295abSYonghong Song 	: __clobber_common);
110*f4b295abSYonghong Song }
111*f4b295abSYonghong Song 
112*f4b295abSYonghong Song SEC("raw_tp")
113*f4b295abSYonghong Song __description("Private stack, callback")
114*f4b295abSYonghong Song __success
115*f4b295abSYonghong Song __arch_x86_64
116*f4b295abSYonghong Song /* for func loop_callback */
117*f4b295abSYonghong Song __jited("func #1")
118*f4b295abSYonghong Song __jited("	endbr64")
119*f4b295abSYonghong Song __jited("	nopl	(%rax,%rax)")
120*f4b295abSYonghong Song __jited("	nopl	(%rax)")
121*f4b295abSYonghong Song __jited("	pushq	%rbp")
122*f4b295abSYonghong Song __jited("	movq	%rsp, %rbp")
123*f4b295abSYonghong Song __jited("	endbr64")
124*f4b295abSYonghong Song __jited("	movabsq	$0x{{.*}}, %r9")
125*f4b295abSYonghong Song __jited("	addq	%gs:0x{{.*}}, %r9")
126*f4b295abSYonghong Song __jited("	pushq	%r9")
127*f4b295abSYonghong Song __jited("	callq")
128*f4b295abSYonghong Song __jited("	popq	%r9")
129*f4b295abSYonghong Song __jited("	movl	$0x2a, %edi")
130*f4b295abSYonghong Song __jited("	movq	%rdi, -0x200(%r9)")
131*f4b295abSYonghong Song __jited("	pushq	%r9")
132*f4b295abSYonghong Song __jited("	callq")
133*f4b295abSYonghong Song __jited("	popq	%r9")
134*f4b295abSYonghong Song __naked void private_stack_callback(void)
135*f4b295abSYonghong Song {
136*f4b295abSYonghong Song 	asm volatile ("			\
137*f4b295abSYonghong Song 	r1 = 1;				\
138*f4b295abSYonghong Song 	r2 = %[loop_callback];		\
139*f4b295abSYonghong Song 	r3 = 0;				\
140*f4b295abSYonghong Song 	r4 = 0;				\
141*f4b295abSYonghong Song 	call %[bpf_loop];		\
142*f4b295abSYonghong Song 	r0 = 0;				\
143*f4b295abSYonghong Song 	exit;				\
144*f4b295abSYonghong Song "	:
145*f4b295abSYonghong Song 	: __imm_ptr(loop_callback),
146*f4b295abSYonghong Song 	  __imm(bpf_loop)
147*f4b295abSYonghong Song 	: __clobber_common);
148*f4b295abSYonghong Song }
149*f4b295abSYonghong Song 
150*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9")
151*f4b295abSYonghong Song __description("Private stack, exception in main prog")
152*f4b295abSYonghong Song __success __retval(0)
153*f4b295abSYonghong Song __arch_x86_64
154*f4b295abSYonghong Song __jited("	pushq	%r9")
155*f4b295abSYonghong Song __jited("	callq")
156*f4b295abSYonghong Song __jited("	popq	%r9")
157*f4b295abSYonghong Song int private_stack_exception_main_prog(void)
158*f4b295abSYonghong Song {
159*f4b295abSYonghong Song 	asm volatile ("			\
160*f4b295abSYonghong Song 	r1 = 42;			\
161*f4b295abSYonghong Song 	*(u64 *)(r10 - 512) = r1;	\
162*f4b295abSYonghong Song "	::: __clobber_common);
163*f4b295abSYonghong Song 
164*f4b295abSYonghong Song 	bpf_throw(0);
165*f4b295abSYonghong Song 	return 0;
166*f4b295abSYonghong Song }
167*f4b295abSYonghong Song 
168*f4b295abSYonghong Song __used static int subprog_exception(void)
169*f4b295abSYonghong Song {
170*f4b295abSYonghong Song 	bpf_throw(0);
171*f4b295abSYonghong Song 	return 0;
172*f4b295abSYonghong Song }
173*f4b295abSYonghong Song 
174*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9")
175*f4b295abSYonghong Song __description("Private stack, exception in subprog")
176*f4b295abSYonghong Song __success __retval(0)
177*f4b295abSYonghong Song __arch_x86_64
178*f4b295abSYonghong Song __jited("	movq	%rdi, -0x200(%r9)")
179*f4b295abSYonghong Song __jited("	pushq	%r9")
180*f4b295abSYonghong Song __jited("	callq")
181*f4b295abSYonghong Song __jited("	popq	%r9")
182*f4b295abSYonghong Song int private_stack_exception_sub_prog(void)
183*f4b295abSYonghong Song {
184*f4b295abSYonghong Song 	asm volatile ("			\
185*f4b295abSYonghong Song 	r1 = 42;			\
186*f4b295abSYonghong Song 	*(u64 *)(r10 - 512) = r1;	\
187*f4b295abSYonghong Song 	call subprog_exception;		\
188*f4b295abSYonghong Song "	::: __clobber_common);
189*f4b295abSYonghong Song 
190*f4b295abSYonghong Song 	return 0;
191*f4b295abSYonghong Song }
192*f4b295abSYonghong Song 
193*f4b295abSYonghong Song int glob;
194*f4b295abSYonghong Song __noinline static void subprog2(int *val)
195*f4b295abSYonghong Song {
196*f4b295abSYonghong Song 	glob += val[0] * 2;
197*f4b295abSYonghong Song }
198*f4b295abSYonghong Song 
199*f4b295abSYonghong Song __noinline static void subprog1(int *val)
200*f4b295abSYonghong Song {
201*f4b295abSYonghong Song 	int tmp[64] = {};
202*f4b295abSYonghong Song 
203*f4b295abSYonghong Song 	tmp[0] = *val;
204*f4b295abSYonghong Song 	subprog2(tmp);
205*f4b295abSYonghong Song }
206*f4b295abSYonghong Song 
207*f4b295abSYonghong Song __noinline static int timer_cb1(void *map, int *key, struct bpf_timer *timer)
208*f4b295abSYonghong Song {
209*f4b295abSYonghong Song 	subprog1(key);
210*f4b295abSYonghong Song 	return 0;
211*f4b295abSYonghong Song }
212*f4b295abSYonghong Song 
213*f4b295abSYonghong Song __noinline static int timer_cb2(void *map, int *key, struct bpf_timer *timer)
214*f4b295abSYonghong Song {
215*f4b295abSYonghong Song 	return 0;
216*f4b295abSYonghong Song }
217*f4b295abSYonghong Song 
218*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9")
219*f4b295abSYonghong Song __description("Private stack, async callback, not nested")
220*f4b295abSYonghong Song __success __retval(0)
221*f4b295abSYonghong Song __arch_x86_64
222*f4b295abSYonghong Song __jited("	movabsq	$0x{{.*}}, %r9")
223*f4b295abSYonghong Song int private_stack_async_callback_1(void)
224*f4b295abSYonghong Song {
225*f4b295abSYonghong Song 	struct bpf_timer *arr_timer;
226*f4b295abSYonghong Song 	int array_key = 0;
227*f4b295abSYonghong Song 
228*f4b295abSYonghong Song 	arr_timer = bpf_map_lookup_elem(&array, &array_key);
229*f4b295abSYonghong Song 	if (!arr_timer)
230*f4b295abSYonghong Song 		return 0;
231*f4b295abSYonghong Song 
232*f4b295abSYonghong Song 	bpf_timer_init(arr_timer, &array, 1);
233*f4b295abSYonghong Song 	bpf_timer_set_callback(arr_timer, timer_cb2);
234*f4b295abSYonghong Song 	bpf_timer_start(arr_timer, 0, 0);
235*f4b295abSYonghong Song 	subprog1(&array_key);
236*f4b295abSYonghong Song 	return 0;
237*f4b295abSYonghong Song }
238*f4b295abSYonghong Song 
239*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9")
240*f4b295abSYonghong Song __description("Private stack, async callback, potential nesting")
241*f4b295abSYonghong Song __success __retval(0)
242*f4b295abSYonghong Song __arch_x86_64
243*f4b295abSYonghong Song __jited("	subq	$0x100, %rsp")
244*f4b295abSYonghong Song int private_stack_async_callback_2(void)
245*f4b295abSYonghong Song {
246*f4b295abSYonghong Song 	struct bpf_timer *arr_timer;
247*f4b295abSYonghong Song 	int array_key = 0;
248*f4b295abSYonghong Song 
249*f4b295abSYonghong Song 	arr_timer = bpf_map_lookup_elem(&array, &array_key);
250*f4b295abSYonghong Song 	if (!arr_timer)
251*f4b295abSYonghong Song 		return 0;
252*f4b295abSYonghong Song 
253*f4b295abSYonghong Song 	bpf_timer_init(arr_timer, &array, 1);
254*f4b295abSYonghong Song 	bpf_timer_set_callback(arr_timer, timer_cb1);
255*f4b295abSYonghong Song 	bpf_timer_start(arr_timer, 0, 0);
256*f4b295abSYonghong Song 	subprog1(&array_key);
257*f4b295abSYonghong Song 	return 0;
258*f4b295abSYonghong Song }
259*f4b295abSYonghong Song 
260*f4b295abSYonghong Song #else
261*f4b295abSYonghong Song 
262*f4b295abSYonghong Song SEC("kprobe")
263*f4b295abSYonghong Song __description("private stack is not supported, use a dummy test")
264*f4b295abSYonghong Song __success
265*f4b295abSYonghong Song int dummy_test(void)
266*f4b295abSYonghong Song {
267*f4b295abSYonghong Song 	return 0;
268*f4b295abSYonghong Song }
269*f4b295abSYonghong Song 
270*f4b295abSYonghong Song #endif
271*f4b295abSYonghong Song 
272*f4b295abSYonghong Song char _license[] SEC("license") = "GPL";
273