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