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

source code of linux/tools/testing/selftests/bpf/progs/verifier_cfg.c