t_mbuf.c revision 314817
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
53static bool
54test_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
91static bool
92test_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
122static bool
123test_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
145static bool
146test_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
187static bool
188test_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
217static bool
218test_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
252static bool
253test_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
292static bool
293test_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
310static bool
311test_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
328static bool
329test_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
346static bool
347test_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
364static bool
365test_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
383static bool
384test_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
402static bool
403test_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
420static bool
421test_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
439static bool
440test_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
458static bool
459test_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
476static bool
477test_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
495static bool
496test_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
514static bool
515test_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
533ATF_TC(bpfjit_mbuf_ldb_abs);
534ATF_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
541ATF_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
554ATF_TC(bpfjit_mbuf_ldh_abs);
555ATF_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
562ATF_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
575ATF_TC(bpfjit_mbuf_ldw_abs);
576ATF_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
583ATF_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
596ATF_TC(bpfjit_mbuf_ldb_ind);
597ATF_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
604ATF_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
617ATF_TC(bpfjit_mbuf_ldh_ind);
618ATF_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
625ATF_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
638ATF_TC(bpfjit_mbuf_ldw_ind);
639ATF_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
646ATF_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
659ATF_TC(bpfjit_mbuf_msh);
660ATF_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
667ATF_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
680ATF_TC(bpfjit_mbuf_ldb_abs_overflow);
681ATF_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
688ATF_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
701ATF_TC(bpfjit_mbuf_ldh_abs_overflow);
702ATF_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
709ATF_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
722ATF_TC(bpfjit_mbuf_ldw_abs_overflow);
723ATF_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
730ATF_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
743ATF_TC(bpfjit_mbuf_ldb_ind_overflow1);
744ATF_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
751ATF_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
764ATF_TC(bpfjit_mbuf_ldb_ind_overflow2);
765ATF_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
772ATF_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
785ATF_TC(bpfjit_mbuf_ldb_ind_overflow3);
786ATF_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
793ATF_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
806ATF_TC(bpfjit_mbuf_ldh_ind_overflow1);
807ATF_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
814ATF_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
827ATF_TC(bpfjit_mbuf_ldh_ind_overflow2);
828ATF_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
835ATF_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
848ATF_TC(bpfjit_mbuf_ldh_ind_overflow3);
849ATF_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
856ATF_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
869ATF_TC(bpfjit_mbuf_ldw_ind_overflow1);
870ATF_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
877ATF_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
890ATF_TC(bpfjit_mbuf_ldw_ind_overflow2);
891ATF_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
898ATF_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
911ATF_TC(bpfjit_mbuf_ldw_ind_overflow3);
912ATF_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
919ATF_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
932ATF_TC(bpfjit_mbuf_msh_overflow);
933ATF_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
940ATF_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
953ATF_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