1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/meta_access.c */
3 
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 SEC("xdp")
9 __description("meta access, test1")
10 __success __retval(0)
11 __naked void meta_access_test1(void)
12 {
13 	asm volatile ("					\
14 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
15 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
16 	r0 = r2;					\
17 	r0 += 8;					\
18 	if r0 > r3 goto l0_%=;				\
19 	r0 = *(u8*)(r2 + 0);				\
20 l0_%=:	r0 = 0;						\
21 	exit;						\
22 "	:
23 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
24 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
25 	: __clobber_all);
26 }
27 
28 SEC("xdp")
29 __description("meta access, test2")
30 __failure __msg("invalid access to packet, off=-8")
31 __naked void meta_access_test2(void)
32 {
33 	asm volatile ("					\
34 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
35 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
36 	r0 = r2;					\
37 	r0 -= 8;					\
38 	r4 = r2;					\
39 	r4 += 8;					\
40 	if r4 > r3 goto l0_%=;				\
41 	r0 = *(u8*)(r0 + 0);				\
42 l0_%=:	r0 = 0;						\
43 	exit;						\
44 "	:
45 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
46 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
47 	: __clobber_all);
48 }
49 
50 SEC("xdp")
51 __description("meta access, test3")
52 __failure __msg("invalid access to packet")
53 __naked void meta_access_test3(void)
54 {
55 	asm volatile ("					\
56 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
57 	r3 = *(u32*)(r1 + %[xdp_md_data_end]);		\
58 	r0 = r2;					\
59 	r0 += 8;					\
60 	if r0 > r3 goto l0_%=;				\
61 	r0 = *(u8*)(r2 + 0);				\
62 l0_%=:	r0 = 0;						\
63 	exit;						\
64 "	:
65 	: __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)),
66 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
67 	: __clobber_all);
68 }
69 
70 SEC("xdp")
71 __description("meta access, test4")
72 __failure __msg("invalid access to packet")
73 __naked void meta_access_test4(void)
74 {
75 	asm volatile ("					\
76 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
77 	r3 = *(u32*)(r1 + %[xdp_md_data_end]);		\
78 	r4 = *(u32*)(r1 + %[xdp_md_data]);		\
79 	r0 = r4;					\
80 	r0 += 8;					\
81 	if r0 > r3 goto l0_%=;				\
82 	r0 = *(u8*)(r2 + 0);				\
83 l0_%=:	r0 = 0;						\
84 	exit;						\
85 "	:
86 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
87 	  __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)),
88 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
89 	: __clobber_all);
90 }
91 
92 SEC("xdp")
93 __description("meta access, test5")
94 __failure __msg("R3 !read_ok")
95 __naked void meta_access_test5(void)
96 {
97 	asm volatile ("					\
98 	r3 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
99 	r4 = *(u32*)(r1 + %[xdp_md_data]);		\
100 	r0 = r3;					\
101 	r0 += 8;					\
102 	if r0 > r4 goto l0_%=;				\
103 	r2 = -8;					\
104 	call %[bpf_xdp_adjust_meta];			\
105 	r0 = *(u8*)(r3 + 0);				\
106 l0_%=:	r0 = 0;						\
107 	exit;						\
108 "	:
109 	: __imm(bpf_xdp_adjust_meta),
110 	  __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
111 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
112 	: __clobber_all);
113 }
114 
115 SEC("xdp")
116 __description("meta access, test6")
117 __failure __msg("invalid access to packet")
118 __naked void meta_access_test6(void)
119 {
120 	asm volatile ("					\
121 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
122 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
123 	r0 = r3;					\
124 	r0 += 8;					\
125 	r4 = r2;					\
126 	r4 += 8;					\
127 	if r4 > r0 goto l0_%=;				\
128 	r0 = *(u8*)(r2 + 0);				\
129 l0_%=:	r0 = 0;						\
130 	exit;						\
131 "	:
132 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
133 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
134 	: __clobber_all);
135 }
136 
137 SEC("xdp")
138 __description("meta access, test7")
139 __success __retval(0)
140 __naked void meta_access_test7(void)
141 {
142 	asm volatile ("					\
143 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
144 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
145 	r0 = r3;					\
146 	r0 += 8;					\
147 	r4 = r2;					\
148 	r4 += 8;					\
149 	if r4 > r3 goto l0_%=;				\
150 	r0 = *(u8*)(r2 + 0);				\
151 l0_%=:	r0 = 0;						\
152 	exit;						\
153 "	:
154 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
155 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
156 	: __clobber_all);
157 }
158 
159 SEC("xdp")
160 __description("meta access, test8")
161 __success __retval(0)
162 __naked void meta_access_test8(void)
163 {
164 	asm volatile ("					\
165 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
166 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
167 	r4 = r2;					\
168 	r4 += 0xFFFF;					\
169 	if r4 > r3 goto l0_%=;				\
170 	r0 = *(u8*)(r2 + 0);				\
171 l0_%=:	r0 = 0;						\
172 	exit;						\
173 "	:
174 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
175 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
176 	: __clobber_all);
177 }
178 
179 SEC("xdp")
180 __description("meta access, test9")
181 __failure __msg("invalid access to packet")
182 __naked void meta_access_test9(void)
183 {
184 	asm volatile ("					\
185 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
186 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
187 	r4 = r2;					\
188 	r4 += 0xFFFF;					\
189 	r4 += 1;					\
190 	if r4 > r3 goto l0_%=;				\
191 	r0 = *(u8*)(r2 + 0);				\
192 l0_%=:	r0 = 0;						\
193 	exit;						\
194 "	:
195 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
196 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
197 	: __clobber_all);
198 }
199 
200 SEC("xdp")
201 __description("meta access, test10")
202 __failure __msg("invalid access to packet")
203 __naked void meta_access_test10(void)
204 {
205 	asm volatile ("					\
206 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
207 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
208 	r4 = *(u32*)(r1 + %[xdp_md_data_end]);		\
209 	r5 = 42;					\
210 	r6 = 24;					\
211 	*(u64*)(r10 - 8) = r5;				\
212 	lock *(u64 *)(r10 - 8) += r6;			\
213 	r5 = *(u64*)(r10 - 8);				\
214 	if r5 > 100 goto l0_%=;				\
215 	r3 += r5;					\
216 	r5 = r3;					\
217 	r6 = r2;					\
218 	r6 += 8;					\
219 	if r6 > r5 goto l0_%=;				\
220 	r2 = *(u8*)(r2 + 0);				\
221 l0_%=:	r0 = 0;						\
222 	exit;						\
223 "	:
224 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
225 	  __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)),
226 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
227 	: __clobber_all);
228 }
229 
230 SEC("xdp")
231 __description("meta access, test11")
232 __success __retval(0)
233 __naked void meta_access_test11(void)
234 {
235 	asm volatile ("					\
236 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
237 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
238 	r5 = 42;					\
239 	r6 = 24;					\
240 	*(u64*)(r10 - 8) = r5;				\
241 	lock *(u64 *)(r10 - 8) += r6;			\
242 	r5 = *(u64*)(r10 - 8);				\
243 	if r5 > 100 goto l0_%=;				\
244 	r2 += r5;					\
245 	r5 = r2;					\
246 	r6 = r2;					\
247 	r6 += 8;					\
248 	if r6 > r3 goto l0_%=;				\
249 	r5 = *(u8*)(r5 + 0);				\
250 l0_%=:	r0 = 0;						\
251 	exit;						\
252 "	:
253 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
254 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
255 	: __clobber_all);
256 }
257 
258 SEC("xdp")
259 __description("meta access, test12")
260 __success __retval(0)
261 __naked void meta_access_test12(void)
262 {
263 	asm volatile ("					\
264 	r2 = *(u32*)(r1 + %[xdp_md_data_meta]);		\
265 	r3 = *(u32*)(r1 + %[xdp_md_data]);		\
266 	r4 = *(u32*)(r1 + %[xdp_md_data_end]);		\
267 	r5 = r3;					\
268 	r5 += 16;					\
269 	if r5 > r4 goto l0_%=;				\
270 	r0 = *(u8*)(r3 + 0);				\
271 	r5 = r2;					\
272 	r5 += 16;					\
273 	if r5 > r3 goto l0_%=;				\
274 	r0 = *(u8*)(r2 + 0);				\
275 l0_%=:	r0 = 0;						\
276 	exit;						\
277 "	:
278 	: __imm_const(xdp_md_data, offsetof(struct xdp_md, data)),
279 	  __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)),
280 	  __imm_const(xdp_md_data_meta, offsetof(struct xdp_md, data_meta))
281 	: __clobber_all);
282 }
283 
284 char _license[] SEC("license") = "GPL";
285