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
8SEC("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);				\
20l0_%=:	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
28SEC("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);				\
42l0_%=:	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
50SEC("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);				\
62l0_%=:	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
70SEC("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);				\
83l0_%=:	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
92SEC("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);				\
106l0_%=:	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
115SEC("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);				\
129l0_%=:	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
137SEC("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);				\
151l0_%=:	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
159SEC("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);				\
171l0_%=:	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
179SEC("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);				\
192l0_%=:	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
200SEC("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);				\
221l0_%=:	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
230SEC("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);				\
250l0_%=:	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
258SEC("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);				\
275l0_%=:	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
284char _license[] SEC("license") = "GPL";
285