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