aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/bpf/progs/verifier_cfg.c
blob: c1f55e1d80a426f3b87c2f13a74176f19bb18e28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// SPDX-License-Identifier: GPL-2.0
/* Converted from tools/testing/selftests/bpf/verifier/cfg.c */

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"

SEC("socket")
__description("unreachable")
__failure __msg("unreachable")
__failure_unpriv
__naked void unreachable(void)
{
	asm volatile ("					\
	exit;						\
	exit;						\
"	::: __clobber_all);
}

SEC("socket")
__description("unreachable2")
__failure __msg("unreachable")
__failure_unpriv
__naked void unreachable2(void)
{
	asm volatile ("					\
	goto l0_%=;					\
	goto l0_%=;					\
l0_%=:	exit;						\
"	::: __clobber_all);
}

SEC("socket")
__description("out of range jump")
__failure __msg("jump out of range")
__failure_unpriv
__naked void out_of_range_jump(void)
{
	asm volatile ("					\
	goto l0_%=;					\
	exit;						\
l0_%=:							\
"	::: __clobber_all);
}

SEC("socket")
__description("out of range jump2")
__failure __msg("jump out of range")
__failure_unpriv
__naked void out_of_range_jump2(void)
{
	asm volatile ("					\
	goto -2;					\
	exit;						\
"	::: __clobber_all);
}

SEC("socket")
__description("loop (back-edge)")
__failure __msg("unreachable insn 1")
__msg_unpriv("back-edge")
__naked void loop_back_edge(void)
{
	asm volatile ("					\
l0_%=:	goto l0_%=;					\
	exit;						\
"	::: __clobber_all);
}

SEC("socket")
__description("loop2 (back-edge)")
__failure __msg("unreachable insn 4")
__msg_unpriv("back-edge")
__naked void loop2_back_edge(void)
{
	asm volatile ("					\
l0_%=:	r1 = r0;					\
	r2 = r0;					\
	r3 = r0;					\
	goto l0_%=;					\
	exit;						\
"	::: __clobber_all);
}

SEC("socket")
__description("conditional loop")
__failure __msg("infinite loop detected")
__msg_unpriv("back-edge")
__naked void conditional_loop(void)
{
	asm volatile ("					\
	r0 = r1;					\
l0_%=:	r2 = r0;					\
	r3 = r0;					\
	if r1 == 0 goto l0_%=;				\
	exit;						\
"	::: __clobber_all);
}

SEC("socket")
__description("conditional loop (2)")
__success
__failure_unpriv __msg_unpriv("back-edge from insn 10 to 11")
__naked void conditional_loop2(void)
{
	asm volatile ("					\
	r9 = 2 ll;					\
	r3 = 0x20 ll;					\
	r4 = 0x35 ll;					\
	r8 = r4;					\
	goto l1_%=;					\
l0_%=:	r9 -= r3;					\
	r9 -= r4;					\
	r9 -= r8;					\
l1_%=:	r8 += r4;					\
	if r8 < 0x64 goto l0_%=;			\
	r0 = r9;					\
	exit;						\
"	::: __clobber_all);
}

SEC("socket")
__description("unconditional loop after conditional jump")
__failure __msg("infinite loop detected")
__failure_unpriv __msg_unpriv("back-edge from insn 3 to 2")
__naked void uncond_loop_after_cond_jmp(void)
{
	asm volatile ("					\
	r0 = 0;						\
	if r0 > 0 goto l1_%=;				\
l0_%=:	r0 = 1;						\
	goto l0_%=;					\
l1_%=:	exit;						\
"	::: __clobber_all);
}


__naked __noinline __used
static unsigned long never_ending_subprog()
{
	asm volatile ("					\
	r0 = r1;					\
	goto -1;					\
"	::: __clobber_all);
}

SEC("socket")
__description("unconditional loop after conditional jump")
/* infinite loop is detected *after* check_cfg() */
__failure __msg("infinite loop detected")
__naked void uncond_loop_in_subprog_after_cond_jmp(void)
{
	asm volatile ("					\
	r0 = 0;						\
	if r0 > 0 goto l1_%=;				\
l0_%=:	r0 += 1;					\
	call never_ending_subprog;			\
l1_%=:	exit;						\
"	::: __clobber_all);
}

char _license[] SEC("license") = "GPL";