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