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
52static bool
53test_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
89static bool
90test_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
119static bool
120test_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
141static bool
142test_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
182static bool
183test_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
211static bool
212test_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
245static bool
246test_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
284static bool
285test_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
301static bool
302test_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
318static bool
319test_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
335static bool
336test_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
352static bool
353test_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
370static bool
371test_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
388static bool
389test_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
405static bool
406test_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
423static bool
424test_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
441static bool
442test_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
458static bool
459test_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
476static bool
477test_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
494static bool
495test_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
512ATF_TC(bpf_mbuf_ldb_abs);
513ATF_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
520ATF_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
533ATF_TC(bpf_mbuf_ldh_abs);
534ATF_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
541ATF_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
554ATF_TC(bpf_mbuf_ldw_abs);
555ATF_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
562ATF_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
575ATF_TC(bpf_mbuf_ldb_ind);
576ATF_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
583ATF_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
596ATF_TC(bpf_mbuf_ldh_ind);
597ATF_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
604ATF_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
617ATF_TC(bpf_mbuf_ldw_ind);
618ATF_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
625ATF_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
638ATF_TC(bpf_mbuf_msh);
639ATF_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
646ATF_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
659ATF_TC(bpf_mbuf_ldb_abs_overflow);
660ATF_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
667ATF_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
680ATF_TC(bpf_mbuf_ldh_abs_overflow);
681ATF_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
688ATF_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
701ATF_TC(bpf_mbuf_ldw_abs_overflow);
702ATF_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
709ATF_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
722ATF_TC(bpf_mbuf_ldb_ind_overflow1);
723ATF_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
730ATF_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
743ATF_TC(bpf_mbuf_ldb_ind_overflow2);
744ATF_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
751ATF_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
764ATF_TC(bpf_mbuf_ldb_ind_overflow3);
765ATF_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
772ATF_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
785ATF_TC(bpf_mbuf_ldh_ind_overflow1);
786ATF_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
793ATF_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
806ATF_TC(bpf_mbuf_ldh_ind_overflow2);
807ATF_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
814ATF_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
827ATF_TC(bpf_mbuf_ldh_ind_overflow3);
828ATF_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
835ATF_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
848ATF_TC(bpf_mbuf_ldw_ind_overflow1);
849ATF_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
856ATF_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
869ATF_TC(bpf_mbuf_ldw_ind_overflow2);
870ATF_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
877ATF_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
890ATF_TC(bpf_mbuf_ldw_ind_overflow3);
891ATF_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
898ATF_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
911ATF_TC(bpf_mbuf_msh_overflow);
912ATF_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
919ATF_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
932ATF_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