xref: /linux/tools/testing/selftests/bpf/progs/verifier_cfg.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/cfg.c */
3 
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 SEC("socket")
9 __description("unreachable")
10 __failure __msg("unreachable")
11 __failure_unpriv
unreachable(void)12 __naked void unreachable(void)
13 {
14 	asm volatile ("					\
15 	exit;						\
16 	exit;						\
17 "	::: __clobber_all);
18 }
19 
20 SEC("socket")
21 __description("unreachable2")
22 __failure __msg("unreachable")
23 __failure_unpriv
unreachable2(void)24 __naked void unreachable2(void)
25 {
26 	asm volatile ("					\
27 	goto l0_%=;					\
28 	goto l0_%=;					\
29 l0_%=:	exit;						\
30 "	::: __clobber_all);
31 }
32 
33 SEC("socket")
34 __description("out of range jump")
35 __failure __msg("jump out of range")
36 __failure_unpriv
out_of_range_jump(void)37 __naked void out_of_range_jump(void)
38 {
39 	asm volatile ("					\
40 	goto l0_%=;					\
41 	exit;						\
42 l0_%=:							\
43 "	::: __clobber_all);
44 }
45 
46 SEC("socket")
47 __description("out of range jump2")
48 __failure __msg("jump out of range")
49 __failure_unpriv
out_of_range_jump2(void)50 __naked void out_of_range_jump2(void)
51 {
52 	asm volatile ("					\
53 	goto -2;					\
54 	exit;						\
55 "	::: __clobber_all);
56 }
57 
58 SEC("socket")
59 __description("loop (back-edge)")
60 __failure __msg("unreachable insn 1")
61 __msg_unpriv("back-edge")
loop_back_edge(void)62 __naked void loop_back_edge(void)
63 {
64 	asm volatile ("					\
65 l0_%=:	goto l0_%=;					\
66 	exit;						\
67 "	::: __clobber_all);
68 }
69 
70 SEC("socket")
71 __description("loop2 (back-edge)")
72 __failure __msg("unreachable insn 4")
73 __msg_unpriv("back-edge")
loop2_back_edge(void)74 __naked void loop2_back_edge(void)
75 {
76 	asm volatile ("					\
77 l0_%=:	r1 = r0;					\
78 	r2 = r0;					\
79 	r3 = r0;					\
80 	goto l0_%=;					\
81 	exit;						\
82 "	::: __clobber_all);
83 }
84 
85 SEC("socket")
86 __description("conditional loop")
87 __failure __msg("infinite loop detected")
88 __msg_unpriv("back-edge")
conditional_loop(void)89 __naked void conditional_loop(void)
90 {
91 	asm volatile ("					\
92 	r0 = r1;					\
93 l0_%=:	r2 = r0;					\
94 	r3 = r0;					\
95 	if r1 == 0 goto l0_%=;				\
96 	exit;						\
97 "	::: __clobber_all);
98 }
99 
100 SEC("socket")
101 __description("conditional loop (2)")
102 __success
103 __failure_unpriv __msg_unpriv("back-edge from insn 10 to 11")
conditional_loop2(void)104 __naked void conditional_loop2(void)
105 {
106 	asm volatile ("					\
107 	r9 = 2 ll;					\
108 	r3 = 0x20 ll;					\
109 	r4 = 0x35 ll;					\
110 	r8 = r4;					\
111 	goto l1_%=;					\
112 l0_%=:	r9 -= r3;					\
113 	r9 -= r4;					\
114 	r9 -= r8;					\
115 l1_%=:	r8 += r4;					\
116 	if r8 < 0x64 goto l0_%=;			\
117 	r0 = r9;					\
118 	exit;						\
119 "	::: __clobber_all);
120 }
121 
122 SEC("socket")
123 __description("unconditional loop after conditional jump")
124 __failure __msg("infinite loop detected")
125 __failure_unpriv __msg_unpriv("back-edge from insn 3 to 2")
uncond_loop_after_cond_jmp(void)126 __naked void uncond_loop_after_cond_jmp(void)
127 {
128 	asm volatile ("					\
129 	r0 = 0;						\
130 	if r0 > 0 goto l1_%=;				\
131 l0_%=:	r0 = 1;						\
132 	goto l0_%=;					\
133 l1_%=:	exit;						\
134 "	::: __clobber_all);
135 }
136 
137 
138 __naked __noinline __used
never_ending_subprog()139 static unsigned long never_ending_subprog()
140 {
141 	asm volatile ("					\
142 	r0 = r1;					\
143 	goto -1;					\
144 "	::: __clobber_all);
145 }
146 
147 SEC("socket")
148 __description("unconditional loop after conditional jump")
149 /* infinite loop is detected *after* check_cfg() */
150 __failure __msg("infinite loop detected")
uncond_loop_in_subprog_after_cond_jmp(void)151 __naked void uncond_loop_in_subprog_after_cond_jmp(void)
152 {
153 	asm volatile ("					\
154 	r0 = 0;						\
155 	if r0 > 0 goto l1_%=;				\
156 l0_%=:	r0 += 1;					\
157 	call never_ending_subprog;			\
158 l1_%=:	exit;						\
159 "	::: __clobber_all);
160 }
161 
162 char _license[] SEC("license") = "GPL";
163