]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/netbsd-tests/net/bpfjit/t_mbuf.c
MFC r314450,r313439:
[FreeBSD/stable/10.git] / contrib / netbsd-tests / net / bpfjit / t_mbuf.c
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 }