xref: /freebsd/contrib/netbsd-tests/net/bpfjit/t_mbuf.c (revision 3b852823339de23e65ffc488229bf75a2896fe2b)
1 /*	$NetBSD: t_mbuf.c,v 1.2 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.2 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 #include <net/bpfjit.h>
37 
38 #include <stdint.h>
39 #include <string.h>
40 
41 #include <rump/rump.h>
42 #include <rump/rump_syscalls.h>
43 
44 #include "../../net/bpf/h_bpf.h"
45 
46 /* XXX: atf-c.h has collisions with mbuf */
47 #undef m_type
48 #undef m_data
49 #include <atf-c.h>
50 
51 #include "h_macros.h"
52 
53 static bool
54 test_ldb_abs(size_t split)
55 {
56 	/* Return a product of all packet bytes. */
57 	static struct bpf_insn insns[] = {
58 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1     */
59 
60 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),  /* A <- P[0]  */
61 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
62 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
63 
64 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 1),  /* A <- P[1]  */
65 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
66 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
67 
68 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 2),  /* A <- P[2]  */
69 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
70 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
71 
72 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),  /* A <- P[3]  */
73 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
74 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
75 
76 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),  /* A <- P[4]  */
77 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */
78 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A      */
79 	};
80 
81 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
82 	const unsigned int res = 120;
83 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
84 
85 	if (!prog_validate(insns, insn_count))
86 		return false;
87 
88 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res;
89 }
90 
91 static bool
92 test_ldh_abs(size_t split)
93 {
94 	static struct bpf_insn insns[] = {
95 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 0),  /* A <- P[0:2]  */
96 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
97 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
98 
99 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 1),  /* A <- P[1:2]  */
100 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
101 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
102 
103 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 2),  /* A <- P[2:2]  */
104 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
105 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
106 
107 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 3),  /* A <- P[3:2]  */
108 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X   */
109 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A        */
110 	};
111 
112 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
113 	const unsigned int res = 0x0a0e; /* 10 14 */
114 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
115 
116 	if (!prog_validate(insns, insn_count))
117 		return false;
118 
119 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res;
120 }
121 
122 static bool
123 test_ldw_abs(size_t split)
124 {
125 	static struct bpf_insn insns[] = {
126 		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),  /* A <- P[0:4] */
127 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
128 		BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A       */
129 
130 		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 1),  /* A <- P[1:4] */
131 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
132 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A       */
133 	};
134 
135 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
136 	const unsigned int res = 0x03050709;
137 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
138 
139 	if (!prog_validate(insns, insn_count))
140 		return false;
141 
142 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res;
143 }
144 
145 static bool
146 test_ldb_ind(size_t split)
147 {
148 	/* Return a sum of all packet bytes. */
149 	static struct bpf_insn insns[] = {
150 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),  /* A <- P[0+X] */
151 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
152 
153 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),  /* A <- P[1+X] */
154 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
155 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
156 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
157 
158 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1      */
159 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),  /* A <- P[1+X] */
160 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
161 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
162 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
163 
164 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1      */
165 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),  /* A <- P[2+X] */
166 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
167 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
168 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A   */
169 
170 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1      */
171 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 3),  /* A <- P[3+X] */
172 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]   */
173 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X  */
174 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A       */
175 	};
176 
177 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
178 	const unsigned int res = 15;
179 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
180 
181 	if (!prog_validate(insns, insn_count))
182 		return false;
183 
184 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res;
185 }
186 
187 static bool
188 test_ldw_ind(size_t split)
189 {
190 	static struct bpf_insn insns[] = {
191 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),  /* A <- P[X+0:4] */
192 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
193 
194 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1        */
195 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),  /* A <- P[X+0:4] */
196 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
197 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
198 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
199 
200 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), /* X <- 0        */
201 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1),  /* A <- P[X+1:4] */
202 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
203 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
204 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A         */
205 	};
206 
207 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
208 	const unsigned int res = 0x05080b0e;
209 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
210 
211 	if (!prog_validate(insns, insn_count))
212 		return false;
213 
214 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res;
215 }
216 
217 static bool
218 test_ldh_ind(size_t split)
219 {
220 	static struct bpf_insn insns[] = {
221 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),  /* A <- P[X+0:2] */
222 		BPF_STMT(BPF_ST, 0),                /* M[0] <- A     */
223 
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, 1),  /* A <- P[X+1: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_ST, 0),                /* M[0] <- A     */
234 
235 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1        */
236 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2),  /* A <- P[X+2:2] */
237 		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0]     */
238 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X    */
239 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A         */
240 	};
241 
242 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
243 	const unsigned int res = 0x0a0e; /* 10 14 */
244 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
245 
246 	if (!prog_validate(insns, insn_count))
247 		return false;
248 
249 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res;
250 }
251 
252 static bool
253 test_msh(size_t split)
254 {
255 	/* Return a product of all packet bytes. */
256 	static struct bpf_insn insns[] = {
257 		BPF_STMT(BPF_LD+BPF_IMM, 1),        /* A <- 1     */
258 
259 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 0), /* X <- 4*(P[0]&0xf)  */
260 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
261 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
262 
263 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1), /* X <- 4*(P[1]&0xf)  */
264 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
265 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
266 
267 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 2), /* X <- 4*(P[2]&0xf)  */
268 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
269 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
270 
271 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 3), /* X <- 4*(P[3]&0xf)  */
272 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
273 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
274 
275 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 4), /* X <- 4*(P[4]&0xf)  */
276 		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X         */
277 		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4         */
278 
279 		BPF_STMT(BPF_RET+BPF_A, 0),         /* ret A      */
280 	};
281 
282 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
283 	const unsigned int res = 120;
284 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
285 
286 	if (!prog_validate(insns, insn_count))
287 		return false;
288 
289 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res;
290 }
291 
292 static bool
293 test_ldb_abs_overflow(size_t split)
294 {
295 	static struct bpf_insn insns[] = {
296 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
297 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
298 		BPF_STMT(BPF_RET+BPF_A, 0),
299 	};
300 
301 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
302 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
303 
304 	if (!prog_validate(insns, insn_count))
305 		return false;
306 
307 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
308 }
309 
310 static bool
311 test_ldh_abs_overflow(size_t split)
312 {
313 	static struct bpf_insn insns[] = {
314 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),
315 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
316 		BPF_STMT(BPF_RET+BPF_A, 0),
317 	};
318 
319 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
320 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
321 
322 	if (!prog_validate(insns, insn_count))
323 		return false;
324 
325 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
326 }
327 
328 static bool
329 test_ldw_abs_overflow(size_t split)
330 {
331 	static struct bpf_insn insns[] = {
332 		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2),
333 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
334 		BPF_STMT(BPF_RET+BPF_A, 0),
335 	};
336 
337 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
338 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
339 
340 	if (!prog_validate(insns, insn_count))
341 		return false;
342 
343 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
344 }
345 
346 static bool
347 test_ldb_ind_overflow1(size_t split)
348 {
349 	static struct bpf_insn insns[] = {
350 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 5),
351 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
352 		BPF_STMT(BPF_RET+BPF_A, 0),
353 	};
354 
355 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
356 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
357 
358 	if (!prog_validate(insns, insn_count))
359 		return false;
360 
361 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
362 }
363 
364 static bool
365 test_ldb_ind_overflow2(size_t split)
366 {
367 	static struct bpf_insn insns[] = {
368 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
369 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),
370 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
371 		BPF_STMT(BPF_RET+BPF_A, 0),
372 	};
373 
374 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
375 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
376 
377 	if (!prog_validate(insns, insn_count))
378 		return false;
379 
380 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
381 }
382 
383 static bool
384 test_ldb_ind_overflow3(size_t split)
385 {
386 	static struct bpf_insn insns[] = {
387 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX),
388 		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1),
389 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
390 		BPF_STMT(BPF_RET+BPF_A, 0),
391 	};
392 
393 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
394 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
395 
396 	if (!prog_validate(insns, insn_count))
397 		return false;
398 
399 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
400 }
401 
402 static bool
403 test_ldh_ind_overflow1(size_t split)
404 {
405 	static struct bpf_insn insns[] = {
406 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 4),
407 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
408 		BPF_STMT(BPF_RET+BPF_A, 0),
409 	};
410 
411 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
412 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
413 
414 	if (!prog_validate(insns, insn_count))
415 		return false;
416 
417 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
418 }
419 
420 static bool
421 test_ldh_ind_overflow2(size_t split)
422 {
423 	static struct bpf_insn insns[] = {
424 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
425 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1),
426 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
427 		BPF_STMT(BPF_RET+BPF_A, 0),
428 	};
429 
430 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
431 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
432 
433 	if (!prog_validate(insns, insn_count))
434 		return false;
435 
436 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
437 }
438 
439 static bool
440 test_ldh_ind_overflow3(size_t split)
441 {
442 	static struct bpf_insn insns[] = {
443 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX),
444 		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1),
445 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
446 		BPF_STMT(BPF_RET+BPF_A, 0),
447 	};
448 
449 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
450 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
451 
452 	if (!prog_validate(insns, insn_count))
453 		return false;
454 
455 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
456 }
457 
458 static bool
459 test_ldw_ind_overflow1(size_t split)
460 {
461 	static struct bpf_insn insns[] = {
462 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2),
463 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
464 		BPF_STMT(BPF_RET+BPF_A, 0),
465 	};
466 
467 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
468 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
469 
470 	if (!prog_validate(insns, insn_count))
471 		return false;
472 
473 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
474 }
475 
476 static bool
477 test_ldw_ind_overflow2(size_t split)
478 {
479 	static struct bpf_insn insns[] = {
480 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
481 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1),
482 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
483 		BPF_STMT(BPF_RET+BPF_A, 0),
484 	};
485 
486 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
487 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
488 
489 	if (!prog_validate(insns, insn_count))
490 		return false;
491 
492 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
493 }
494 
495 static bool
496 test_ldw_ind_overflow3(size_t split)
497 {
498 	static struct bpf_insn insns[] = {
499 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX),
500 		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1),
501 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
502 		BPF_STMT(BPF_RET+BPF_A, 0),
503 	};
504 
505 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
506 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
507 
508 	if (!prog_validate(insns, insn_count))
509 		return false;
510 
511 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
512 }
513 
514 static bool
515 test_msh_overflow(size_t split)
516 {
517 	static struct bpf_insn insns[] = {
518 		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 5),
519 		BPF_STMT(BPF_MISC+BPF_TXA, 0),
520 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
521 		BPF_STMT(BPF_RET+BPF_A, 0),
522 	};
523 
524 	static unsigned char P[] = { 1, 2, 3, 4, 5 };
525 	const size_t insn_count = sizeof(insns) / sizeof(insns[0]);
526 
527 	if (!prog_validate(insns, insn_count))
528 		return false;
529 
530 	return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0;
531 }
532 
533 ATF_TC(bpfjit_mbuf_ldb_abs);
534 ATF_TC_HEAD(bpfjit_mbuf_ldb_abs, tc)
535 {
536 
537 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS "
538 	    "loads bytes from mbuf correctly");
539 }
540 
541 ATF_TC_BODY(bpfjit_mbuf_ldb_abs, tc)
542 {
543 
544 	RZ(rump_init());
545 
546 	ATF_CHECK(test_ldb_abs(0));
547 	ATF_CHECK(test_ldb_abs(1));
548 	ATF_CHECK(test_ldb_abs(2));
549 	ATF_CHECK(test_ldb_abs(3));
550 	ATF_CHECK(test_ldb_abs(4));
551 	ATF_CHECK(test_ldb_abs(5));
552 }
553 
554 ATF_TC(bpfjit_mbuf_ldh_abs);
555 ATF_TC_HEAD(bpfjit_mbuf_ldh_abs, tc)
556 {
557 
558 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS "
559 	    "loads halfwords from mbuf correctly");
560 }
561 
562 ATF_TC_BODY(bpfjit_mbuf_ldh_abs, tc)
563 {
564 
565 	RZ(rump_init());
566 
567 	ATF_CHECK(test_ldh_abs(0));
568 	ATF_CHECK(test_ldh_abs(1));
569 	ATF_CHECK(test_ldh_abs(2));
570 	ATF_CHECK(test_ldh_abs(3));
571 	ATF_CHECK(test_ldh_abs(4));
572 	ATF_CHECK(test_ldh_abs(5));
573 }
574 
575 ATF_TC(bpfjit_mbuf_ldw_abs);
576 ATF_TC_HEAD(bpfjit_mbuf_ldw_abs, tc)
577 {
578 
579 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS "
580 	    "loads words from mbuf correctly");
581 }
582 
583 ATF_TC_BODY(bpfjit_mbuf_ldw_abs, tc)
584 {
585 
586 	RZ(rump_init());
587 
588 	ATF_CHECK(test_ldw_abs(0));
589 	ATF_CHECK(test_ldw_abs(1));
590 	ATF_CHECK(test_ldw_abs(2));
591 	ATF_CHECK(test_ldw_abs(3));
592 	ATF_CHECK(test_ldw_abs(4));
593 	ATF_CHECK(test_ldw_abs(5));
594 }
595 
596 ATF_TC(bpfjit_mbuf_ldb_ind);
597 ATF_TC_HEAD(bpfjit_mbuf_ldb_ind, tc)
598 {
599 
600 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND "
601 	    "loads bytes from mbuf correctly");
602 }
603 
604 ATF_TC_BODY(bpfjit_mbuf_ldb_ind, tc)
605 {
606 
607 	RZ(rump_init());
608 
609 	ATF_CHECK(test_ldb_ind(0));
610 	ATF_CHECK(test_ldb_ind(1));
611 	ATF_CHECK(test_ldb_ind(2));
612 	ATF_CHECK(test_ldb_ind(3));
613 	ATF_CHECK(test_ldb_ind(4));
614 	ATF_CHECK(test_ldb_ind(5));
615 }
616 
617 ATF_TC(bpfjit_mbuf_ldh_ind);
618 ATF_TC_HEAD(bpfjit_mbuf_ldh_ind, tc)
619 {
620 
621 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND "
622 	    "loads halfwords from mbuf correctly");
623 }
624 
625 ATF_TC_BODY(bpfjit_mbuf_ldh_ind, tc)
626 {
627 
628 	RZ(rump_init());
629 
630 	ATF_CHECK(test_ldh_ind(0));
631 	ATF_CHECK(test_ldh_ind(1));
632 	ATF_CHECK(test_ldh_ind(2));
633 	ATF_CHECK(test_ldh_ind(3));
634 	ATF_CHECK(test_ldh_ind(4));
635 	ATF_CHECK(test_ldh_ind(5));
636 }
637 
638 ATF_TC(bpfjit_mbuf_ldw_ind);
639 ATF_TC_HEAD(bpfjit_mbuf_ldw_ind, tc)
640 {
641 
642 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND "
643 	    "loads words from mbuf correctly");
644 }
645 
646 ATF_TC_BODY(bpfjit_mbuf_ldw_ind, tc)
647 {
648 
649 	RZ(rump_init());
650 
651 	ATF_CHECK(test_ldw_ind(0));
652 	ATF_CHECK(test_ldw_ind(1));
653 	ATF_CHECK(test_ldw_ind(2));
654 	ATF_CHECK(test_ldw_ind(3));
655 	ATF_CHECK(test_ldw_ind(4));
656 	ATF_CHECK(test_ldw_ind(5));
657 }
658 
659 ATF_TC(bpfjit_mbuf_msh);
660 ATF_TC_HEAD(bpfjit_mbuf_msh, tc)
661 {
662 
663 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH "
664 	    "loads bytes from mbuf correctly");
665 }
666 
667 ATF_TC_BODY(bpfjit_mbuf_msh, tc)
668 {
669 
670 	RZ(rump_init());
671 
672 	ATF_CHECK(test_msh(0));
673 	ATF_CHECK(test_msh(1));
674 	ATF_CHECK(test_msh(2));
675 	ATF_CHECK(test_msh(3));
676 	ATF_CHECK(test_msh(4));
677 	ATF_CHECK(test_msh(5));
678 }
679 
680 ATF_TC(bpfjit_mbuf_ldb_abs_overflow);
681 ATF_TC_HEAD(bpfjit_mbuf_ldb_abs_overflow, tc)
682 {
683 
684 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS "
685 	    "with out-of-bounds index aborts a filter program");
686 }
687 
688 ATF_TC_BODY(bpfjit_mbuf_ldb_abs_overflow, tc)
689 {
690 
691 	RZ(rump_init());
692 
693 	ATF_CHECK(test_ldb_abs_overflow(0));
694 	ATF_CHECK(test_ldb_abs_overflow(1));
695 	ATF_CHECK(test_ldb_abs_overflow(2));
696 	ATF_CHECK(test_ldb_abs_overflow(3));
697 	ATF_CHECK(test_ldb_abs_overflow(4));
698 	ATF_CHECK(test_ldb_abs_overflow(5));
699 }
700 
701 ATF_TC(bpfjit_mbuf_ldh_abs_overflow);
702 ATF_TC_HEAD(bpfjit_mbuf_ldh_abs_overflow, tc)
703 {
704 
705 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS "
706 	    "with out-of-bounds index aborts a filter program");
707 }
708 
709 ATF_TC_BODY(bpfjit_mbuf_ldh_abs_overflow, tc)
710 {
711 
712 	RZ(rump_init());
713 
714 	ATF_CHECK(test_ldh_abs_overflow(0));
715 	ATF_CHECK(test_ldh_abs_overflow(1));
716 	ATF_CHECK(test_ldh_abs_overflow(2));
717 	ATF_CHECK(test_ldh_abs_overflow(3));
718 	ATF_CHECK(test_ldh_abs_overflow(4));
719 	ATF_CHECK(test_ldh_abs_overflow(5));
720 }
721 
722 ATF_TC(bpfjit_mbuf_ldw_abs_overflow);
723 ATF_TC_HEAD(bpfjit_mbuf_ldw_abs_overflow, tc)
724 {
725 
726 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS "
727 	    "with out-of-bounds index aborts a filter program");
728 }
729 
730 ATF_TC_BODY(bpfjit_mbuf_ldw_abs_overflow, tc)
731 {
732 
733 	RZ(rump_init());
734 
735 	ATF_CHECK(test_ldw_abs_overflow(0));
736 	ATF_CHECK(test_ldw_abs_overflow(1));
737 	ATF_CHECK(test_ldw_abs_overflow(2));
738 	ATF_CHECK(test_ldw_abs_overflow(3));
739 	ATF_CHECK(test_ldw_abs_overflow(4));
740 	ATF_CHECK(test_ldw_abs_overflow(5));
741 }
742 
743 ATF_TC(bpfjit_mbuf_ldb_ind_overflow1);
744 ATF_TC_HEAD(bpfjit_mbuf_ldb_ind_overflow1, 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(bpfjit_mbuf_ldb_ind_overflow1, tc)
752 {
753 
754 	RZ(rump_init());
755 
756 	ATF_CHECK(test_ldb_ind_overflow1(0));
757 	ATF_CHECK(test_ldb_ind_overflow1(1));
758 	ATF_CHECK(test_ldb_ind_overflow1(2));
759 	ATF_CHECK(test_ldb_ind_overflow1(3));
760 	ATF_CHECK(test_ldb_ind_overflow1(4));
761 	ATF_CHECK(test_ldb_ind_overflow1(5));
762 }
763 
764 ATF_TC(bpfjit_mbuf_ldb_ind_overflow2);
765 ATF_TC_HEAD(bpfjit_mbuf_ldb_ind_overflow2, 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(bpfjit_mbuf_ldb_ind_overflow2, tc)
773 {
774 
775 	RZ(rump_init());
776 
777 	ATF_CHECK(test_ldb_ind_overflow2(0));
778 	ATF_CHECK(test_ldb_ind_overflow2(1));
779 	ATF_CHECK(test_ldb_ind_overflow2(2));
780 	ATF_CHECK(test_ldb_ind_overflow2(3));
781 	ATF_CHECK(test_ldb_ind_overflow2(4));
782 	ATF_CHECK(test_ldb_ind_overflow2(5));
783 }
784 
785 ATF_TC(bpfjit_mbuf_ldb_ind_overflow3);
786 ATF_TC_HEAD(bpfjit_mbuf_ldb_ind_overflow3, tc)
787 {
788 
789 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND "
790 	    "with out-of-bounds index aborts a filter program");
791 }
792 
793 ATF_TC_BODY(bpfjit_mbuf_ldb_ind_overflow3, tc)
794 {
795 
796 	RZ(rump_init());
797 
798 	ATF_CHECK(test_ldb_ind_overflow3(0));
799 	ATF_CHECK(test_ldb_ind_overflow3(1));
800 	ATF_CHECK(test_ldb_ind_overflow3(2));
801 	ATF_CHECK(test_ldb_ind_overflow3(3));
802 	ATF_CHECK(test_ldb_ind_overflow3(4));
803 	ATF_CHECK(test_ldb_ind_overflow3(5));
804 }
805 
806 ATF_TC(bpfjit_mbuf_ldh_ind_overflow1);
807 ATF_TC_HEAD(bpfjit_mbuf_ldh_ind_overflow1, 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(bpfjit_mbuf_ldh_ind_overflow1, tc)
815 {
816 
817 	RZ(rump_init());
818 
819 	ATF_CHECK(test_ldh_ind_overflow1(0));
820 	ATF_CHECK(test_ldh_ind_overflow1(1));
821 	ATF_CHECK(test_ldh_ind_overflow1(2));
822 	ATF_CHECK(test_ldh_ind_overflow1(3));
823 	ATF_CHECK(test_ldh_ind_overflow1(4));
824 	ATF_CHECK(test_ldh_ind_overflow1(5));
825 }
826 
827 ATF_TC(bpfjit_mbuf_ldh_ind_overflow2);
828 ATF_TC_HEAD(bpfjit_mbuf_ldh_ind_overflow2, 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(bpfjit_mbuf_ldh_ind_overflow2, tc)
836 {
837 
838 	RZ(rump_init());
839 
840 	ATF_CHECK(test_ldh_ind_overflow2(0));
841 	ATF_CHECK(test_ldh_ind_overflow2(1));
842 	ATF_CHECK(test_ldh_ind_overflow2(2));
843 	ATF_CHECK(test_ldh_ind_overflow2(3));
844 	ATF_CHECK(test_ldh_ind_overflow2(4));
845 	ATF_CHECK(test_ldh_ind_overflow2(5));
846 }
847 
848 ATF_TC(bpfjit_mbuf_ldh_ind_overflow3);
849 ATF_TC_HEAD(bpfjit_mbuf_ldh_ind_overflow3, tc)
850 {
851 
852 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND "
853 	    "with out-of-bounds index aborts a filter program");
854 }
855 
856 ATF_TC_BODY(bpfjit_mbuf_ldh_ind_overflow3, tc)
857 {
858 
859 	RZ(rump_init());
860 
861 	ATF_CHECK(test_ldh_ind_overflow3(0));
862 	ATF_CHECK(test_ldh_ind_overflow3(1));
863 	ATF_CHECK(test_ldh_ind_overflow3(2));
864 	ATF_CHECK(test_ldh_ind_overflow3(3));
865 	ATF_CHECK(test_ldh_ind_overflow3(4));
866 	ATF_CHECK(test_ldh_ind_overflow3(5));
867 }
868 
869 ATF_TC(bpfjit_mbuf_ldw_ind_overflow1);
870 ATF_TC_HEAD(bpfjit_mbuf_ldw_ind_overflow1, 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(bpfjit_mbuf_ldw_ind_overflow1, tc)
878 {
879 
880 	RZ(rump_init());
881 
882 	ATF_CHECK(test_ldw_ind_overflow1(0));
883 	ATF_CHECK(test_ldw_ind_overflow1(1));
884 	ATF_CHECK(test_ldw_ind_overflow1(2));
885 	ATF_CHECK(test_ldw_ind_overflow1(3));
886 	ATF_CHECK(test_ldw_ind_overflow1(4));
887 	ATF_CHECK(test_ldw_ind_overflow1(5));
888 }
889 
890 ATF_TC(bpfjit_mbuf_ldw_ind_overflow2);
891 ATF_TC_HEAD(bpfjit_mbuf_ldw_ind_overflow2, 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(bpfjit_mbuf_ldw_ind_overflow2, tc)
899 {
900 
901 	RZ(rump_init());
902 
903 	ATF_CHECK(test_ldw_ind_overflow2(0));
904 	ATF_CHECK(test_ldw_ind_overflow2(1));
905 	ATF_CHECK(test_ldw_ind_overflow2(2));
906 	ATF_CHECK(test_ldw_ind_overflow2(3));
907 	ATF_CHECK(test_ldw_ind_overflow2(4));
908 	ATF_CHECK(test_ldw_ind_overflow2(5));
909 }
910 
911 ATF_TC(bpfjit_mbuf_ldw_ind_overflow3);
912 ATF_TC_HEAD(bpfjit_mbuf_ldw_ind_overflow3, tc)
913 {
914 
915 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND "
916 	    "with out-of-bounds index aborts a filter program");
917 }
918 
919 ATF_TC_BODY(bpfjit_mbuf_ldw_ind_overflow3, tc)
920 {
921 
922 	RZ(rump_init());
923 
924 	ATF_CHECK(test_ldw_ind_overflow3(0));
925 	ATF_CHECK(test_ldw_ind_overflow3(1));
926 	ATF_CHECK(test_ldw_ind_overflow3(2));
927 	ATF_CHECK(test_ldw_ind_overflow3(3));
928 	ATF_CHECK(test_ldw_ind_overflow3(4));
929 	ATF_CHECK(test_ldw_ind_overflow3(5));
930 }
931 
932 ATF_TC(bpfjit_mbuf_msh_overflow);
933 ATF_TC_HEAD(bpfjit_mbuf_msh_overflow, tc)
934 {
935 
936 	atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH "
937 	    "with out-of-bounds index aborts a filter program");
938 }
939 
940 ATF_TC_BODY(bpfjit_mbuf_msh_overflow, tc)
941 {
942 
943 	RZ(rump_init());
944 
945 	ATF_CHECK(test_msh_overflow(0));
946 	ATF_CHECK(test_msh_overflow(1));
947 	ATF_CHECK(test_msh_overflow(2));
948 	ATF_CHECK(test_msh_overflow(3));
949 	ATF_CHECK(test_msh_overflow(4));
950 	ATF_CHECK(test_msh_overflow(5));
951 }
952 
953 ATF_TP_ADD_TCS(tp)
954 {
955 
956 	/*
957 	 * For every new test please also add a similar test
958 	 * to ../../net/bpf/t_mbuf.c
959 	 */
960 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_abs);
961 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_abs);
962 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_abs);
963 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind);
964 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind);
965 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind);
966 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_msh);
967 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_abs_overflow);
968 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_abs_overflow);
969 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_abs_overflow);
970 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind_overflow1);
971 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind_overflow2);
972 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind_overflow3);
973 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind_overflow1);
974 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind_overflow2);
975 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind_overflow3);
976 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind_overflow1);
977 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind_overflow2);
978 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind_overflow3);
979 	ATF_TP_ADD_TC(tp, bpfjit_mbuf_msh_overflow);
980 
981 	return atf_no_error();
982 }
983