1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Converted from tools/testing/selftests/bpf/verifier/bounds_deduction.c */ |
3 | |
4 | #include <linux/bpf.h> |
5 | #include <bpf/bpf_helpers.h> |
6 | #include "bpf_misc.h" |
7 | |
8 | SEC("socket" ) |
9 | __description("check deducing bounds from const, 1" ) |
10 | __failure __msg("R0 tried to subtract pointer from scalar" ) |
11 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
12 | __naked void deducing_bounds_from_const_1(void) |
13 | { |
14 | asm volatile (" \ |
15 | r0 = 1; \ |
16 | if r0 s>= 1 goto l0_%=; \ |
17 | l0_%=: r0 -= r1; \ |
18 | exit; \ |
19 | " ::: __clobber_all); |
20 | } |
21 | |
22 | SEC("socket" ) |
23 | __description("check deducing bounds from const, 2" ) |
24 | __success __failure_unpriv |
25 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
26 | __retval(1) |
27 | __naked void deducing_bounds_from_const_2(void) |
28 | { |
29 | asm volatile (" \ |
30 | r0 = 1; \ |
31 | if r0 s>= 1 goto l0_%=; \ |
32 | exit; \ |
33 | l0_%=: if r0 s<= 1 goto l1_%=; \ |
34 | exit; \ |
35 | l1_%=: r1 -= r0; \ |
36 | exit; \ |
37 | " ::: __clobber_all); |
38 | } |
39 | |
40 | SEC("socket" ) |
41 | __description("check deducing bounds from const, 3" ) |
42 | __failure __msg("R0 tried to subtract pointer from scalar" ) |
43 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
44 | __naked void deducing_bounds_from_const_3(void) |
45 | { |
46 | asm volatile (" \ |
47 | r0 = 0; \ |
48 | if r0 s<= 0 goto l0_%=; \ |
49 | l0_%=: r0 -= r1; \ |
50 | exit; \ |
51 | " ::: __clobber_all); |
52 | } |
53 | |
54 | SEC("socket" ) |
55 | __description("check deducing bounds from const, 4" ) |
56 | __success __failure_unpriv |
57 | __msg_unpriv("R6 has pointer with unsupported alu operation" ) |
58 | __retval(0) |
59 | __naked void deducing_bounds_from_const_4(void) |
60 | { |
61 | asm volatile (" \ |
62 | r6 = r1; \ |
63 | r0 = 0; \ |
64 | if r0 s<= 0 goto l0_%=; \ |
65 | exit; \ |
66 | l0_%=: if r0 s>= 0 goto l1_%=; \ |
67 | exit; \ |
68 | l1_%=: r6 -= r0; \ |
69 | exit; \ |
70 | " ::: __clobber_all); |
71 | } |
72 | |
73 | SEC("socket" ) |
74 | __description("check deducing bounds from const, 5" ) |
75 | __failure __msg("R0 tried to subtract pointer from scalar" ) |
76 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
77 | __naked void deducing_bounds_from_const_5(void) |
78 | { |
79 | asm volatile (" \ |
80 | r0 = 0; \ |
81 | if r0 s>= 1 goto l0_%=; \ |
82 | r0 -= r1; \ |
83 | l0_%=: exit; \ |
84 | " ::: __clobber_all); |
85 | } |
86 | |
87 | SEC("socket" ) |
88 | __description("check deducing bounds from const, 6" ) |
89 | __failure __msg("R0 tried to subtract pointer from scalar" ) |
90 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
91 | __naked void deducing_bounds_from_const_6(void) |
92 | { |
93 | asm volatile (" \ |
94 | r0 = 0; \ |
95 | if r0 s>= 0 goto l0_%=; \ |
96 | exit; \ |
97 | l0_%=: r0 -= r1; \ |
98 | exit; \ |
99 | " ::: __clobber_all); |
100 | } |
101 | |
102 | SEC("socket" ) |
103 | __description("check deducing bounds from const, 7" ) |
104 | __failure __msg("dereference of modified ctx ptr" ) |
105 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
106 | __flag(BPF_F_ANY_ALIGNMENT) |
107 | __naked void deducing_bounds_from_const_7(void) |
108 | { |
109 | asm volatile (" \ |
110 | r0 = %[__imm_0]; \ |
111 | if r0 s>= 0 goto l0_%=; \ |
112 | l0_%=: r1 -= r0; \ |
113 | r0 = *(u32*)(r1 + %[__sk_buff_mark]); \ |
114 | exit; \ |
115 | " : |
116 | : __imm_const(__imm_0, ~0), |
117 | __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) |
118 | : __clobber_all); |
119 | } |
120 | |
121 | SEC("socket" ) |
122 | __description("check deducing bounds from const, 8" ) |
123 | __failure __msg("negative offset ctx ptr R1 off=-1 disallowed" ) |
124 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
125 | __flag(BPF_F_ANY_ALIGNMENT) |
126 | __naked void deducing_bounds_from_const_8(void) |
127 | { |
128 | asm volatile (" \ |
129 | r0 = %[__imm_0]; \ |
130 | if r0 s>= 0 goto l0_%=; \ |
131 | r1 += r0; \ |
132 | l0_%=: r0 = *(u32*)(r1 + %[__sk_buff_mark]); \ |
133 | exit; \ |
134 | " : |
135 | : __imm_const(__imm_0, ~0), |
136 | __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) |
137 | : __clobber_all); |
138 | } |
139 | |
140 | SEC("socket" ) |
141 | __description("check deducing bounds from const, 9" ) |
142 | __failure __msg("R0 tried to subtract pointer from scalar" ) |
143 | __msg_unpriv("R1 has pointer with unsupported alu operation" ) |
144 | __naked void deducing_bounds_from_const_9(void) |
145 | { |
146 | asm volatile (" \ |
147 | r0 = 0; \ |
148 | if r0 s>= 0 goto l0_%=; \ |
149 | l0_%=: r0 -= r1; \ |
150 | exit; \ |
151 | " ::: __clobber_all); |
152 | } |
153 | |
154 | SEC("socket" ) |
155 | __description("check deducing bounds from const, 10" ) |
156 | __failure |
157 | __msg("math between ctx pointer and register with unbounded min value is not allowed" ) |
158 | __failure_unpriv |
159 | __naked void deducing_bounds_from_const_10(void) |
160 | { |
161 | asm volatile (" \ |
162 | r0 = 0; \ |
163 | if r0 s<= 0 goto l0_%=; \ |
164 | l0_%=: /* Marks reg as unknown. */ \ |
165 | r0 = -r0; \ |
166 | r0 -= r1; \ |
167 | exit; \ |
168 | " ::: __clobber_all); |
169 | } |
170 | |
171 | char _license[] SEC("license" ) = "GPL" ; |
172 | |