1 /* $OpenBSD: bpf_filter.c,v 1.34 2020/08/03 03:21:24 dlg Exp $ */ 2 /* $NetBSD: bpf_filter.c,v 1.12 1996/02/13 22:00:00 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1990, 1991, 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from the Stanford/CMU enet packet filter, 9 * (net/enet.c) distributed as part of 4.3BSD, and code contributed 10 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 11 * Berkeley Laboratory. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)bpf_filter.c 8.1 (Berkeley) 6/10/93 38 */ 39 40 #include <sys/param.h> 41 #include <sys/time.h> 42 #ifndef _KERNEL 43 #include <stdlib.h> 44 #include <string.h> 45 #include "pcap.h" 46 #else 47 #include <sys/systm.h> 48 #endif 49 50 #include <sys/endian.h> 51 52 #ifdef _KERNEL 53 extern int bpf_maxbufsize; 54 #define Static 55 #else /* _KERNEL */ 56 #define Static static 57 #endif /* _KERNEL */ 58 59 #include <net/bpf.h> 60 61 struct bpf_mem { 62 const u_char *pkt; 63 u_int len; 64 }; 65 66 Static u_int32_t bpf_mem_ldw(const void *, u_int32_t, int *); 67 Static u_int32_t bpf_mem_ldh(const void *, u_int32_t, int *); 68 Static u_int32_t bpf_mem_ldb(const void *, u_int32_t, int *); 69 70 static const struct bpf_ops bpf_mem_ops = { 71 bpf_mem_ldw, 72 bpf_mem_ldh, 73 bpf_mem_ldb, 74 }; 75 76 Static u_int32_t 77 bpf_mem_ldw(const void *mem, u_int32_t k, int *err) 78 { 79 const struct bpf_mem *bm = mem; 80 u_int32_t v; 81 82 *err = 1; 83 84 if (k + sizeof(v) > bm->len) 85 return (0); 86 87 memcpy(&v, bm->pkt + k, sizeof(v)); 88 89 *err = 0; 90 return ntohl(v); 91 } 92 93 Static u_int32_t 94 bpf_mem_ldh(const void *mem, u_int32_t k, int *err) 95 { 96 const struct bpf_mem *bm = mem; 97 u_int16_t v; 98 99 *err = 1; 100 101 if (k + sizeof(v) > bm->len) 102 return (0); 103 104 memcpy(&v, bm->pkt + k, sizeof(v)); 105 106 *err = 0; 107 return ntohs(v); 108 } 109 110 Static u_int32_t 111 bpf_mem_ldb(const void *mem, u_int32_t k, int *err) 112 { 113 const struct bpf_mem *bm = mem; 114 115 *err = 1; 116 117 if (k >= bm->len) 118 return (0); 119 120 *err = 0; 121 return bm->pkt[k]; 122 } 123 124 /* 125 * Execute the filter program starting at pc on the packet p 126 * wirelen is the length of the original packet 127 * buflen is the amount of data present 128 */ 129 u_int 130 bpf_filter(const struct bpf_insn *pc, const u_char *pkt, 131 u_int wirelen, u_int buflen) 132 { 133 struct bpf_mem bm; 134 135 bm.pkt = pkt; 136 bm.len = buflen; 137 138 return _bpf_filter(pc, &bpf_mem_ops, &bm, wirelen); 139 } 140 141 u_int 142 _bpf_filter(const struct bpf_insn *pc, const struct bpf_ops *ops, 143 const void *pkt, u_int wirelen) 144 { 145 u_int32_t A = 0, X = 0; 146 u_int32_t k; 147 int32_t mem[BPF_MEMWORDS]; 148 int err; 149 150 if (pc == NULL) { 151 /* 152 * No filter means accept all. 153 */ 154 return (u_int)-1; 155 } 156 157 memset(mem, 0, sizeof(mem)); 158 159 --pc; 160 while (1) { 161 ++pc; 162 switch (pc->code) { 163 164 default: 165 #ifdef _KERNEL 166 return 0; 167 #else 168 abort(); 169 #endif 170 case BPF_RET|BPF_K: 171 return (u_int)pc->k; 172 173 case BPF_RET|BPF_A: 174 return (u_int)A; 175 176 case BPF_LD|BPF_W|BPF_ABS: 177 A = ops->ldw(pkt, pc->k, &err); 178 if (err != 0) 179 return 0; 180 continue; 181 182 case BPF_LD|BPF_H|BPF_ABS: 183 A = ops->ldh(pkt, pc->k, &err); 184 if (err != 0) 185 return 0; 186 continue; 187 188 case BPF_LD|BPF_B|BPF_ABS: 189 A = ops->ldb(pkt, pc->k, &err); 190 if (err != 0) 191 return 0; 192 continue; 193 194 case BPF_LD|BPF_W|BPF_LEN: 195 A = wirelen; 196 continue; 197 198 case BPF_LDX|BPF_W|BPF_LEN: 199 X = wirelen; 200 continue; 201 202 case BPF_LD|BPF_W|BPF_RND: 203 A = arc4random(); 204 continue; 205 206 case BPF_LD|BPF_W|BPF_IND: 207 k = X + pc->k; 208 A = ops->ldw(pkt, k, &err); 209 if (err != 0) 210 return 0; 211 continue; 212 213 case BPF_LD|BPF_H|BPF_IND: 214 k = X + pc->k; 215 A = ops->ldh(pkt, k, &err); 216 if (err != 0) 217 return 0; 218 continue; 219 220 case BPF_LD|BPF_B|BPF_IND: 221 k = X + pc->k; 222 A = ops->ldb(pkt, k, &err); 223 if (err != 0) 224 return 0; 225 continue; 226 227 case BPF_LDX|BPF_MSH|BPF_B: 228 X = ops->ldb(pkt, pc->k, &err); 229 if (err != 0) 230 return 0; 231 X &= 0xf; 232 X <<= 2; 233 continue; 234 235 case BPF_LD|BPF_IMM: 236 A = pc->k; 237 continue; 238 239 case BPF_LDX|BPF_IMM: 240 X = pc->k; 241 continue; 242 243 case BPF_LD|BPF_MEM: 244 A = mem[pc->k]; 245 continue; 246 247 case BPF_LDX|BPF_MEM: 248 X = mem[pc->k]; 249 continue; 250 251 case BPF_ST: 252 mem[pc->k] = A; 253 continue; 254 255 case BPF_STX: 256 mem[pc->k] = X; 257 continue; 258 259 case BPF_JMP|BPF_JA: 260 pc += pc->k; 261 continue; 262 263 case BPF_JMP|BPF_JGT|BPF_K: 264 pc += (A > pc->k) ? pc->jt : pc->jf; 265 continue; 266 267 case BPF_JMP|BPF_JGE|BPF_K: 268 pc += (A >= pc->k) ? pc->jt : pc->jf; 269 continue; 270 271 case BPF_JMP|BPF_JEQ|BPF_K: 272 pc += (A == pc->k) ? pc->jt : pc->jf; 273 continue; 274 275 case BPF_JMP|BPF_JSET|BPF_K: 276 pc += (A & pc->k) ? pc->jt : pc->jf; 277 continue; 278 279 case BPF_JMP|BPF_JGT|BPF_X: 280 pc += (A > X) ? pc->jt : pc->jf; 281 continue; 282 283 case BPF_JMP|BPF_JGE|BPF_X: 284 pc += (A >= X) ? pc->jt : pc->jf; 285 continue; 286 287 case BPF_JMP|BPF_JEQ|BPF_X: 288 pc += (A == X) ? pc->jt : pc->jf; 289 continue; 290 291 case BPF_JMP|BPF_JSET|BPF_X: 292 pc += (A & X) ? pc->jt : pc->jf; 293 continue; 294 295 case BPF_ALU|BPF_ADD|BPF_X: 296 A += X; 297 continue; 298 299 case BPF_ALU|BPF_SUB|BPF_X: 300 A -= X; 301 continue; 302 303 case BPF_ALU|BPF_MUL|BPF_X: 304 A *= X; 305 continue; 306 307 case BPF_ALU|BPF_DIV|BPF_X: 308 if (X == 0) 309 return 0; 310 A /= X; 311 continue; 312 313 case BPF_ALU|BPF_AND|BPF_X: 314 A &= X; 315 continue; 316 317 case BPF_ALU|BPF_OR|BPF_X: 318 A |= X; 319 continue; 320 321 case BPF_ALU|BPF_LSH|BPF_X: 322 A <<= X; 323 continue; 324 325 case BPF_ALU|BPF_RSH|BPF_X: 326 A >>= X; 327 continue; 328 329 case BPF_ALU|BPF_ADD|BPF_K: 330 A += pc->k; 331 continue; 332 333 case BPF_ALU|BPF_SUB|BPF_K: 334 A -= pc->k; 335 continue; 336 337 case BPF_ALU|BPF_MUL|BPF_K: 338 A *= pc->k; 339 continue; 340 341 case BPF_ALU|BPF_DIV|BPF_K: 342 A /= pc->k; 343 continue; 344 345 case BPF_ALU|BPF_AND|BPF_K: 346 A &= pc->k; 347 continue; 348 349 case BPF_ALU|BPF_OR|BPF_K: 350 A |= pc->k; 351 continue; 352 353 case BPF_ALU|BPF_LSH|BPF_K: 354 A <<= pc->k; 355 continue; 356 357 case BPF_ALU|BPF_RSH|BPF_K: 358 A >>= pc->k; 359 continue; 360 361 case BPF_ALU|BPF_NEG: 362 A = -A; 363 continue; 364 365 case BPF_MISC|BPF_TAX: 366 X = A; 367 continue; 368 369 case BPF_MISC|BPF_TXA: 370 A = X; 371 continue; 372 } 373 } 374 } 375 376 #ifdef _KERNEL 377 /* 378 * Return true if the 'fcode' is a valid filter program. 379 * The constraints are that each jump be forward and to a valid 380 * code and memory operations use valid addresses. The code 381 * must terminate with either an accept or reject. 382 * 383 * The kernel needs to be able to verify an application's filter code. 384 * Otherwise, a bogus program could easily crash the system. 385 */ 386 int 387 bpf_validate(struct bpf_insn *f, int len) 388 { 389 u_int i, from; 390 struct bpf_insn *p; 391 392 if (len < 1 || len > BPF_MAXINSNS) 393 return 0; 394 395 for (i = 0; i < len; ++i) { 396 p = &f[i]; 397 switch (BPF_CLASS(p->code)) { 398 /* 399 * Check that memory operations use valid addresses. 400 */ 401 case BPF_LD: 402 case BPF_LDX: 403 switch (BPF_MODE(p->code)) { 404 case BPF_IMM: 405 break; 406 case BPF_ABS: 407 case BPF_IND: 408 case BPF_MSH: 409 /* 410 * More strict check with actual packet length 411 * is done runtime. 412 */ 413 if (p->k >= bpf_maxbufsize) 414 return 0; 415 break; 416 case BPF_MEM: 417 if (p->k >= BPF_MEMWORDS) 418 return 0; 419 break; 420 case BPF_LEN: 421 case BPF_RND: 422 break; 423 default: 424 return 0; 425 } 426 break; 427 case BPF_ST: 428 case BPF_STX: 429 if (p->k >= BPF_MEMWORDS) 430 return 0; 431 break; 432 case BPF_ALU: 433 switch (BPF_OP(p->code)) { 434 case BPF_ADD: 435 case BPF_SUB: 436 case BPF_MUL: 437 case BPF_OR: 438 case BPF_AND: 439 case BPF_LSH: 440 case BPF_RSH: 441 case BPF_NEG: 442 break; 443 case BPF_DIV: 444 /* 445 * Check for constant division by 0. 446 */ 447 if (BPF_SRC(p->code) == BPF_K && p->k == 0) 448 return 0; 449 break; 450 default: 451 return 0; 452 } 453 break; 454 case BPF_JMP: 455 /* 456 * Check that jumps are forward, and within 457 * the code block. 458 */ 459 from = i + 1; 460 switch (BPF_OP(p->code)) { 461 case BPF_JA: 462 if (from + p->k < from || from + p->k >= len) 463 return 0; 464 break; 465 case BPF_JEQ: 466 case BPF_JGT: 467 case BPF_JGE: 468 case BPF_JSET: 469 if (from + p->jt >= len || from + p->jf >= len) 470 return 0; 471 break; 472 default: 473 return 0; 474 } 475 break; 476 case BPF_RET: 477 break; 478 case BPF_MISC: 479 break; 480 default: 481 return 0; 482 } 483 484 } 485 return BPF_CLASS(f[len - 1].code) == BPF_RET; 486 } 487 #endif 488