xref: /freebsd/contrib/netbsd-tests/net/bpf/t_mbuf.c (revision d4eeb02986980bf33dd56c41ceb9fc5f180c0d47)
1 /*	$NetBSD: t_mbuf.c,v 1.3 2017/01/13 21:30:42 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2014 Alexander Nasonov.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: t_mbuf.c,v 1.3 2017/01/13 21:30:42 christos Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/mbuf.h>
34 
35 #include <net/bpf.h>
36 
37 #include <stdint.h>
38 #include <string.h>
39 
40 #include <rump/rump.h>
41 #include <rump/rump_syscalls.h>
42 
43 #include "../../net/bpf/h_bpf.h"
44 
45 /* XXX: atf-c.h has collisions with mbuf */
46 #undef m_type
47 #undef m_data
48 #include <atf-c.h>
49 
50 #include "h_macros.h"
51 
52 static bool
53 test_ldb_abs(size_t split)
54 {
55 	/* Return a product of all packet bytes. */
56 	static struct bpf_insn insns[] = {
57 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1     */
58 
59 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),  /* A <- P[0]  */
60 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
61 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
62 
63 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 1),  /* A <- P[1]  */
64 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
65 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
66 
67 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 2),  /* A <- P[2]  */
68 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
69 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
70 
71 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),  /* A <- P[3]  */
72 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
73 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
74 
75 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),  /* A <- P[4]  */
76 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
77 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A      */
78 	};
79 
80 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
81 	const unsigned int res = 120;
82 
83 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
84 		return false;
85 
86 	return interp_prog_mchain2(insns, P, sizeof(P), split) == res;
87 }
88 
89 static bool
90 test_ldh_abs(size_t split)
91 {
92 	static struct bpf_insn insns[] = {
93 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 0),  /* A <- P[0:2]  */
94 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
95 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
96 
97 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 1),  /* A <- P[1:2]  */
98 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
99 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
100 
101 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 2),  /* A <- P[2:2]  */
102 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
103 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
104 
105 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 3),  /* A <- P[3:2]  */
106 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
107 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A        */
108 	};
109 
110 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
111 	const unsigned int res = 0x0a0e; /* 10 14 */
112 
113 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
114 		return false;
115 
116 	return interp_prog_mchain2(insns, P, sizeof(P), split) == res;
117 }
118 
119 static bool
120 test_ldw_abs(size_t split)
121 {
122 	static struct bpf_insn insns[] = {
123 		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),  /* A <- P[0:4] */
124 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
125 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
126 
127 		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 1),  /* A <- P[1:4] */
128 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
129 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A       */
130 	};
131 
132 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
133 	const unsigned int res = 0x03050709;
134 
135 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
136 		return false;
137 
138 	return interp_prog_mchain2(insns, P, sizeof(P), split) == res;
139 }
140 
141 static bool
142 test_ldb_ind(size_t split)
143 {
144 	/* Return a sum of all packet bytes. */
145 	static struct bpf_insn insns[] = {
146 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),  /* A <- P[0+X] */
147 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
148 
149 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),  /* A <- P[1+X] */
150 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
151 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
152 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
153 
154 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1      */
155 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),  /* A <- P[1+X] */
156 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
157 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
158 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
159 
160 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1      */
161 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),  /* A <- P[2+X] */
162 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
163 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
164 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
165 
166 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1      */
167 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 3),  /* A <- P[3+X] */
168 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
169 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
170 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A       */
171 	};
172 
173 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
174 	const unsigned int res = 15;
175 
176 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
177 		return false;
178 
179 	return interp_prog_mchain2(insns, P, sizeof(P), split) == res;
180 }
181 
182 static bool
183 test_ldw_ind(size_t split)
184 {
185 	static struct bpf_insn insns[] = {
186 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),  /* A <- P[X+0:4] */
187 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
188 
189 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1        */
190 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),  /* A <- P[X+0:4] */
191 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
192 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
193 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
194 
195 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), /* X <- 0        */
196 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1),  /* A <- P[X+1:4] */
197 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
198 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
199 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A         */
200 	};
201 
202 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
203 	const unsigned int res = 0x05080b0e;
204 
205 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
206 		return false;
207 
208 	return interp_prog_mchain2(insns, P, sizeof(P), split) == res;
209 }
210 
211 static bool
212 test_ldh_ind(size_t split)
213 {
214 	static struct bpf_insn insns[] = {
215 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),  /* A <- P[X+0:2] */
216 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
217 
218 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1),  /* A <- P[X+1:2] */
219 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
220 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
221 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
222 
223 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1        */
224 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1),  /* A <- P[X+1:2] */
225 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
226 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
227 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
228 
229 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1        */
230 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2),  /* A <- P[X+2:2] */
231 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
232 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
233 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A         */
234 	};
235 
236 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
237 	const unsigned int res = 0x0a0e; /* 10 14 */
238 
239 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
240 		return false;
241 
242 	return interp_prog_mchain2(insns, P, sizeof(P), split) == res;
243 }
244 
245 static bool
246 test_msh(size_t split)
247 {
248 	/* Return a product of all packet bytes. */
249 	static struct bpf_insn insns[] = {
250 		BPF_STMT(BPF_LD+BPF_IMM, 1),        /* A <- 1     */
251 
252 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 0), /* X <- 4*(P[0]&0xf)  */
253 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
254 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
255 
256 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1), /* X <- 4*(P[1]&0xf)  */
257 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
258 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
259 
260 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 2), /* X <- 4*(P[2]&0xf)  */
261 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
262 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
263 
264 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 3), /* X <- 4*(P[3]&0xf)  */
265 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
266 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
267 
268 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 4), /* X <- 4*(P[4]&0xf)  */
269 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
270 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
271 
272 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A      */
273 	};
274 
275 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
276 	const unsigned int res = 120;
277 
278 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
279 		return false;
280 
281 	return interp_prog_mchain2(insns, P, sizeof(P), split) == res;
282 }
283 
284 static bool
285 test_ldb_abs_overflow(size_t split)
286 {
287 	static struct bpf_insn insns[] = {
288 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
289 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
290 		BPF_STMT(BPF_RET+BPF_A, 0),
291 	};
292 
293 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
294 
295 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
296 		return false;
297 
298 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
299 }
300 
301 static bool
302 test_ldh_abs_overflow(size_t split)
303 {
304 	static struct bpf_insn insns[] = {
305 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),
306 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
307 		BPF_STMT(BPF_RET+BPF_A, 0),
308 	};
309 
310 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
311 
312 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
313 		return false;
314 
315 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
316 }
317 
318 static bool
319 test_ldw_abs_overflow(size_t split)
320 {
321 	static struct bpf_insn insns[] = {
322 		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2),
323 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
324 		BPF_STMT(BPF_RET+BPF_A, 0),
325 	};
326 
327 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
328 
329 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
330 		return false;
331 
332 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
333 }
334 
335 static bool
336 test_ldb_ind_overflow1(size_t split)
337 {
338 	static struct bpf_insn insns[] = {
339 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 5),
340 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
341 		BPF_STMT(BPF_RET+BPF_A, 0),
342 	};
343 
344 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
345 
346 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
347 		return false;
348 
349 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
350 }
351 
352 static bool
353 test_ldb_ind_overflow2(size_t split)
354 {
355 	static struct bpf_insn insns[] = {
356 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
357 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),
358 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
359 		BPF_STMT(BPF_RET+BPF_A, 0),
360 	};
361 
362 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
363 
364 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
365 		return false;
366 
367 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
368 }
369 
370 static bool
371 test_ldb_ind_overflow3(size_t split)
372 {
373 	static struct bpf_insn insns[] = {
374 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX),
375 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),
376 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
377 		BPF_STMT(BPF_RET+BPF_A, 0),
378 	};
379 
380 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
381 
382 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
383 		return false;
384 
385 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
386 }
387 
388 static bool
389 test_ldh_ind_overflow1(size_t split)
390 {
391 	static struct bpf_insn insns[] = {
392 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 4),
393 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
394 		BPF_STMT(BPF_RET+BPF_A, 0),
395 	};
396 
397 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
398 
399 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
400 		return false;
401 
402 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
403 }
404 
405 static bool
406 test_ldh_ind_overflow2(size_t split)
407 {
408 	static struct bpf_insn insns[] = {
409 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
410 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1),
411 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
412 		BPF_STMT(BPF_RET+BPF_A, 0),
413 	};
414 
415 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
416 
417 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
418 		return false;
419 
420 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
421 }
422 
423 static bool
424 test_ldh_ind_overflow3(size_t split)
425 {
426 	static struct bpf_insn insns[] = {
427 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX),
428 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1),
429 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
430 		BPF_STMT(BPF_RET+BPF_A, 0),
431 	};
432 
433 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
434 
435 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
436 		return false;
437 
438 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
439 }
440 
441 static bool
442 test_ldw_ind_overflow1(size_t split)
443 {
444 	static struct bpf_insn insns[] = {
445 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2),
446 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
447 		BPF_STMT(BPF_RET+BPF_A, 0),
448 	};
449 
450 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
451 
452 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
453 		return false;
454 
455 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
456 }
457 
458 static bool
459 test_ldw_ind_overflow2(size_t split)
460 {
461 	static struct bpf_insn insns[] = {
462 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
463 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1),
464 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
465 		BPF_STMT(BPF_RET+BPF_A, 0),
466 	};
467 
468 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
469 
470 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
471 		return false;
472 
473 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
474 }
475 
476 static bool
477 test_ldw_ind_overflow3(size_t split)
478 {
479 	static struct bpf_insn insns[] = {
480 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX),
481 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1),
482 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
483 		BPF_STMT(BPF_RET+BPF_A, 0),
484 	};
485 
486 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
487 
488 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
489 		return false;
490 
491 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
492 }
493 
494 static bool
495 test_msh_overflow(size_t split)
496 {
497 	static struct bpf_insn insns[] = {
498 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 5),
499 		BPF_STMT(BPF_MISC+BPF_TXA, 0),
500 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
501 		BPF_STMT(BPF_RET+BPF_A, 0),
502 	};
503 
504 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
505 
506 	if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0])))
507 		return false;
508 
509 	return interp_prog_mchain2(insns, P, sizeof(P), split) == 0;
510 }
511 
512 ATF_TC(bpf_mbuf_ldb_abs);
513 ATF_TC_HEAD(bpf_mbuf_ldb_abs, tc)
514 {
515 
516 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS "
517 	    "loads bytes from mbuf correctly");
518 }
519 
520 ATF_TC_BODY(bpf_mbuf_ldb_abs, tc)
521 {
522 
523 	RZ(rump_init());
524 
525 	ATF_CHECK(test_ldb_abs(0));
526 	ATF_CHECK(test_ldb_abs(1));
527 	ATF_CHECK(test_ldb_abs(2));
528 	ATF_CHECK(test_ldb_abs(3));
529 	ATF_CHECK(test_ldb_abs(4));
530 	ATF_CHECK(test_ldb_abs(5));
531 }
532 
533 ATF_TC(bpf_mbuf_ldh_abs);
534 ATF_TC_HEAD(bpf_mbuf_ldh_abs, tc)
535 {
536 
537 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS "
538 	    "loads halfwords from mbuf correctly");
539 }
540 
541 ATF_TC_BODY(bpf_mbuf_ldh_abs, tc)
542 {
543 
544 	RZ(rump_init());
545 
546 	ATF_CHECK(test_ldh_abs(0));
547 	ATF_CHECK(test_ldh_abs(1));
548 	ATF_CHECK(test_ldh_abs(2));
549 	ATF_CHECK(test_ldh_abs(3));
550 	ATF_CHECK(test_ldh_abs(4));
551 	ATF_CHECK(test_ldh_abs(5));
552 }
553 
554 ATF_TC(bpf_mbuf_ldw_abs);
555 ATF_TC_HEAD(bpf_mbuf_ldw_abs, tc)
556 {
557 
558 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS "
559 	    "loads words from mbuf correctly");
560 }
561 
562 ATF_TC_BODY(bpf_mbuf_ldw_abs, tc)
563 {
564 
565 	RZ(rump_init());
566 
567 	ATF_CHECK(test_ldw_abs(0));
568 	ATF_CHECK(test_ldw_abs(1));
569 	ATF_CHECK(test_ldw_abs(2));
570 	ATF_CHECK(test_ldw_abs(3));
571 	ATF_CHECK(test_ldw_abs(4));
572 	ATF_CHECK(test_ldw_abs(5));
573 }
574 
575 ATF_TC(bpf_mbuf_ldb_ind);
576 ATF_TC_HEAD(bpf_mbuf_ldb_ind, tc)
577 {
578 
579 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND "
580 	    "loads bytes from mbuf correctly");
581 }
582 
583 ATF_TC_BODY(bpf_mbuf_ldb_ind, tc)
584 {
585 
586 	RZ(rump_init());
587 
588 	ATF_CHECK(test_ldb_ind(0));
589 	ATF_CHECK(test_ldb_ind(1));
590 	ATF_CHECK(test_ldb_ind(2));
591 	ATF_CHECK(test_ldb_ind(3));
592 	ATF_CHECK(test_ldb_ind(4));
593 	ATF_CHECK(test_ldb_ind(5));
594 }
595 
596 ATF_TC(bpf_mbuf_ldh_ind);
597 ATF_TC_HEAD(bpf_mbuf_ldh_ind, tc)
598 {
599 
600 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND "
601 	    "loads halfwords from mbuf correctly");
602 }
603 
604 ATF_TC_BODY(bpf_mbuf_ldh_ind, tc)
605 {
606 
607 	RZ(rump_init());
608 
609 	ATF_CHECK(test_ldh_ind(0));
610 	ATF_CHECK(test_ldh_ind(1));
611 	ATF_CHECK(test_ldh_ind(2));
612 	ATF_CHECK(test_ldh_ind(3));
613 	ATF_CHECK(test_ldh_ind(4));
614 	ATF_CHECK(test_ldh_ind(5));
615 }
616 
617 ATF_TC(bpf_mbuf_ldw_ind);
618 ATF_TC_HEAD(bpf_mbuf_ldw_ind, tc)
619 {
620 
621 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND "
622 	    "loads words from mbuf correctly");
623 }
624 
625 ATF_TC_BODY(bpf_mbuf_ldw_ind, tc)
626 {
627 
628 	RZ(rump_init());
629 
630 	ATF_CHECK(test_ldw_ind(0));
631 	ATF_CHECK(test_ldw_ind(1));
632 	ATF_CHECK(test_ldw_ind(2));
633 	ATF_CHECK(test_ldw_ind(3));
634 	ATF_CHECK(test_ldw_ind(4));
635 	ATF_CHECK(test_ldw_ind(5));
636 }
637 
638 ATF_TC(bpf_mbuf_msh);
639 ATF_TC_HEAD(bpf_mbuf_msh, tc)
640 {
641 
642 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH "
643 	    "loads bytes from mbuf correctly");
644 }
645 
646 ATF_TC_BODY(bpf_mbuf_msh, tc)
647 {
648 
649 	RZ(rump_init());
650 
651 	ATF_CHECK(test_msh(0));
652 	ATF_CHECK(test_msh(1));
653 	ATF_CHECK(test_msh(2));
654 	ATF_CHECK(test_msh(3));
655 	ATF_CHECK(test_msh(4));
656 	ATF_CHECK(test_msh(5));
657 }
658 
659 ATF_TC(bpf_mbuf_ldb_abs_overflow);
660 ATF_TC_HEAD(bpf_mbuf_ldb_abs_overflow, tc)
661 {
662 
663 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS "
664 	    "with out-of-bounds index aborts a filter program");
665 }
666 
667 ATF_TC_BODY(bpf_mbuf_ldb_abs_overflow, tc)
668 {
669 
670 	RZ(rump_init());
671 
672 	ATF_CHECK(test_ldb_abs_overflow(0));
673 	ATF_CHECK(test_ldb_abs_overflow(1));
674 	ATF_CHECK(test_ldb_abs_overflow(2));
675 	ATF_CHECK(test_ldb_abs_overflow(3));
676 	ATF_CHECK(test_ldb_abs_overflow(4));
677 	ATF_CHECK(test_ldb_abs_overflow(5));
678 }
679 
680 ATF_TC(bpf_mbuf_ldh_abs_overflow);
681 ATF_TC_HEAD(bpf_mbuf_ldh_abs_overflow, tc)
682 {
683 
684 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS "
685 	    "with out-of-bounds index aborts a filter program");
686 }
687 
688 ATF_TC_BODY(bpf_mbuf_ldh_abs_overflow, tc)
689 {
690 
691 	RZ(rump_init());
692 
693 	ATF_CHECK(test_ldh_abs_overflow(0));
694 	ATF_CHECK(test_ldh_abs_overflow(1));
695 	ATF_CHECK(test_ldh_abs_overflow(2));
696 	ATF_CHECK(test_ldh_abs_overflow(3));
697 	ATF_CHECK(test_ldh_abs_overflow(4));
698 	ATF_CHECK(test_ldh_abs_overflow(5));
699 }
700 
701 ATF_TC(bpf_mbuf_ldw_abs_overflow);
702 ATF_TC_HEAD(bpf_mbuf_ldw_abs_overflow, tc)
703 {
704 
705 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS "
706 	    "with out-of-bounds index aborts a filter program");
707 }
708 
709 ATF_TC_BODY(bpf_mbuf_ldw_abs_overflow, tc)
710 {
711 
712 	RZ(rump_init());
713 
714 	ATF_CHECK(test_ldw_abs_overflow(0));
715 	ATF_CHECK(test_ldw_abs_overflow(1));
716 	ATF_CHECK(test_ldw_abs_overflow(2));
717 	ATF_CHECK(test_ldw_abs_overflow(3));
718 	ATF_CHECK(test_ldw_abs_overflow(4));
719 	ATF_CHECK(test_ldw_abs_overflow(5));
720 }
721 
722 ATF_TC(bpf_mbuf_ldb_ind_overflow1);
723 ATF_TC_HEAD(bpf_mbuf_ldb_ind_overflow1, tc)
724 {
725 
726 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND "
727 	    "with out-of-bounds index aborts a filter program");
728 }
729 
730 ATF_TC_BODY(bpf_mbuf_ldb_ind_overflow1, tc)
731 {
732 
733 	RZ(rump_init());
734 
735 	ATF_CHECK(test_ldb_ind_overflow1(0));
736 	ATF_CHECK(test_ldb_ind_overflow1(1));
737 	ATF_CHECK(test_ldb_ind_overflow1(2));
738 	ATF_CHECK(test_ldb_ind_overflow1(3));
739 	ATF_CHECK(test_ldb_ind_overflow1(4));
740 	ATF_CHECK(test_ldb_ind_overflow1(5));
741 }
742 
743 ATF_TC(bpf_mbuf_ldb_ind_overflow2);
744 ATF_TC_HEAD(bpf_mbuf_ldb_ind_overflow2, tc)
745 {
746 
747 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND "
748 	    "with out-of-bounds index aborts a filter program");
749 }
750 
751 ATF_TC_BODY(bpf_mbuf_ldb_ind_overflow2, tc)
752 {
753 
754 	RZ(rump_init());
755 
756 	ATF_CHECK(test_ldb_ind_overflow2(0));
757 	ATF_CHECK(test_ldb_ind_overflow2(1));
758 	ATF_CHECK(test_ldb_ind_overflow2(2));
759 	ATF_CHECK(test_ldb_ind_overflow2(3));
760 	ATF_CHECK(test_ldb_ind_overflow2(4));
761 	ATF_CHECK(test_ldb_ind_overflow2(5));
762 }
763 
764 ATF_TC(bpf_mbuf_ldb_ind_overflow3);
765 ATF_TC_HEAD(bpf_mbuf_ldb_ind_overflow3, tc)
766 {
767 
768 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND "
769 	    "with out-of-bounds index aborts a filter program");
770 }
771 
772 ATF_TC_BODY(bpf_mbuf_ldb_ind_overflow3, tc)
773 {
774 
775 	RZ(rump_init());
776 
777 	ATF_CHECK(test_ldb_ind_overflow3(0));
778 	ATF_CHECK(test_ldb_ind_overflow3(1));
779 	ATF_CHECK(test_ldb_ind_overflow3(2));
780 	ATF_CHECK(test_ldb_ind_overflow3(3));
781 	ATF_CHECK(test_ldb_ind_overflow3(4));
782 	ATF_CHECK(test_ldb_ind_overflow3(5));
783 }
784 
785 ATF_TC(bpf_mbuf_ldh_ind_overflow1);
786 ATF_TC_HEAD(bpf_mbuf_ldh_ind_overflow1, tc)
787 {
788 
789 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND "
790 	    "with out-of-bounds index aborts a filter program");
791 }
792 
793 ATF_TC_BODY(bpf_mbuf_ldh_ind_overflow1, tc)
794 {
795 
796 	RZ(rump_init());
797 
798 	ATF_CHECK(test_ldh_ind_overflow1(0));
799 	ATF_CHECK(test_ldh_ind_overflow1(1));
800 	ATF_CHECK(test_ldh_ind_overflow1(2));
801 	ATF_CHECK(test_ldh_ind_overflow1(3));
802 	ATF_CHECK(test_ldh_ind_overflow1(4));
803 	ATF_CHECK(test_ldh_ind_overflow1(5));
804 }
805 
806 ATF_TC(bpf_mbuf_ldh_ind_overflow2);
807 ATF_TC_HEAD(bpf_mbuf_ldh_ind_overflow2, tc)
808 {
809 
810 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND "
811 	    "with out-of-bounds index aborts a filter program");
812 }
813 
814 ATF_TC_BODY(bpf_mbuf_ldh_ind_overflow2, tc)
815 {
816 
817 	RZ(rump_init());
818 
819 	ATF_CHECK(test_ldh_ind_overflow2(0));
820 	ATF_CHECK(test_ldh_ind_overflow2(1));
821 	ATF_CHECK(test_ldh_ind_overflow2(2));
822 	ATF_CHECK(test_ldh_ind_overflow2(3));
823 	ATF_CHECK(test_ldh_ind_overflow2(4));
824 	ATF_CHECK(test_ldh_ind_overflow2(5));
825 }
826 
827 ATF_TC(bpf_mbuf_ldh_ind_overflow3);
828 ATF_TC_HEAD(bpf_mbuf_ldh_ind_overflow3, tc)
829 {
830 
831 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND "
832 	    "with out-of-bounds index aborts a filter program");
833 }
834 
835 ATF_TC_BODY(bpf_mbuf_ldh_ind_overflow3, tc)
836 {
837 
838 	RZ(rump_init());
839 
840 	ATF_CHECK(test_ldh_ind_overflow3(0));
841 	ATF_CHECK(test_ldh_ind_overflow3(1));
842 	ATF_CHECK(test_ldh_ind_overflow3(2));
843 	ATF_CHECK(test_ldh_ind_overflow3(3));
844 	ATF_CHECK(test_ldh_ind_overflow3(4));
845 	ATF_CHECK(test_ldh_ind_overflow3(5));
846 }
847 
848 ATF_TC(bpf_mbuf_ldw_ind_overflow1);
849 ATF_TC_HEAD(bpf_mbuf_ldw_ind_overflow1, tc)
850 {
851 
852 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND "
853 	    "with out-of-bounds index aborts a filter program");
854 }
855 
856 ATF_TC_BODY(bpf_mbuf_ldw_ind_overflow1, tc)
857 {
858 
859 	RZ(rump_init());
860 
861 	ATF_CHECK(test_ldw_ind_overflow1(0));
862 	ATF_CHECK(test_ldw_ind_overflow1(1));
863 	ATF_CHECK(test_ldw_ind_overflow1(2));
864 	ATF_CHECK(test_ldw_ind_overflow1(3));
865 	ATF_CHECK(test_ldw_ind_overflow1(4));
866 	ATF_CHECK(test_ldw_ind_overflow1(5));
867 }
868 
869 ATF_TC(bpf_mbuf_ldw_ind_overflow2);
870 ATF_TC_HEAD(bpf_mbuf_ldw_ind_overflow2, tc)
871 {
872 
873 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND "
874 	    "with out-of-bounds index aborts a filter program");
875 }
876 
877 ATF_TC_BODY(bpf_mbuf_ldw_ind_overflow2, tc)
878 {
879 
880 	RZ(rump_init());
881 
882 	ATF_CHECK(test_ldw_ind_overflow2(0));
883 	ATF_CHECK(test_ldw_ind_overflow2(1));
884 	ATF_CHECK(test_ldw_ind_overflow2(2));
885 	ATF_CHECK(test_ldw_ind_overflow2(3));
886 	ATF_CHECK(test_ldw_ind_overflow2(4));
887 	ATF_CHECK(test_ldw_ind_overflow2(5));
888 }
889 
890 ATF_TC(bpf_mbuf_ldw_ind_overflow3);
891 ATF_TC_HEAD(bpf_mbuf_ldw_ind_overflow3, tc)
892 {
893 
894 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND "
895 	    "with out-of-bounds index aborts a filter program");
896 }
897 
898 ATF_TC_BODY(bpf_mbuf_ldw_ind_overflow3, tc)
899 {
900 
901 	RZ(rump_init());
902 
903 	ATF_CHECK(test_ldw_ind_overflow3(0));
904 	ATF_CHECK(test_ldw_ind_overflow3(1));
905 	ATF_CHECK(test_ldw_ind_overflow3(2));
906 	ATF_CHECK(test_ldw_ind_overflow3(3));
907 	ATF_CHECK(test_ldw_ind_overflow3(4));
908 	ATF_CHECK(test_ldw_ind_overflow3(5));
909 }
910 
911 ATF_TC(bpf_mbuf_msh_overflow);
912 ATF_TC_HEAD(bpf_mbuf_msh_overflow, tc)
913 {
914 
915 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH "
916 	    "with out-of-bounds index aborts a filter program");
917 }
918 
919 ATF_TC_BODY(bpf_mbuf_msh_overflow, tc)
920 {
921 
922 	RZ(rump_init());
923 
924 	ATF_CHECK(test_msh_overflow(0));
925 	ATF_CHECK(test_msh_overflow(1));
926 	ATF_CHECK(test_msh_overflow(2));
927 	ATF_CHECK(test_msh_overflow(3));
928 	ATF_CHECK(test_msh_overflow(4));
929 	ATF_CHECK(test_msh_overflow(5));
930 }
931 
932 ATF_TP_ADD_TCS(tp)
933 {
934 
935 	/*
936 	 * For every new test please also add a similar test
937 	 * to ../../net/bpfjit/t_mbuf.c
938 	 */
939 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_abs);
940 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_abs);
941 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_abs);
942 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind);
943 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind);
944 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind);
945 	ATF_TP_ADD_TC(tp, bpf_mbuf_msh);
946 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_abs_overflow);
947 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_abs_overflow);
948 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_abs_overflow);
949 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind_overflow1);
950 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind_overflow2);
951 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind_overflow3);
952 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind_overflow1);
953 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind_overflow2);
954 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind_overflow3);
955 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind_overflow1);
956 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind_overflow2);
957 	ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind_overflow3);
958 	ATF_TP_ADD_TC(tp, bpf_mbuf_msh_overflow);
959 
960 	return atf_no_error();
961 }
962