1 /* $OpenBSD: bpf_filter.c,v 1.33 2017/09/08 05:36:53 deraadt 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_IND: 203 k = X + pc->k; 204 A = ops->ldw(pkt, k, &err); 205 if (err != 0) 206 return 0; 207 continue; 208 209 case BPF_LD|BPF_H|BPF_IND: 210 k = X + pc->k; 211 A = ops->ldh(pkt, k, &err); 212 if (err != 0) 213 return 0; 214 continue; 215 216 case BPF_LD|BPF_B|BPF_IND: 217 k = X + pc->k; 218 A = ops->ldb(pkt, k, &err); 219 if (err != 0) 220 return 0; 221 continue; 222 223 case BPF_LDX|BPF_MSH|BPF_B: 224 X = ops->ldb(pkt, pc->k, &err); 225 if (err != 0) 226 return 0; 227 X &= 0xf; 228 X <<= 2; 229 continue; 230 231 case BPF_LD|BPF_IMM: 232 A = pc->k; 233 continue; 234 235 case BPF_LDX|BPF_IMM: 236 X = pc->k; 237 continue; 238 239 case BPF_LD|BPF_MEM: 240 A = mem[pc->k]; 241 continue; 242 243 case BPF_LDX|BPF_MEM: 244 X = mem[pc->k]; 245 continue; 246 247 case BPF_ST: 248 mem[pc->k] = A; 249 continue; 250 251 case BPF_STX: 252 mem[pc->k] = X; 253 continue; 254 255 case BPF_JMP|BPF_JA: 256 pc += pc->k; 257 continue; 258 259 case BPF_JMP|BPF_JGT|BPF_K: 260 pc += (A > pc->k) ? pc->jt : pc->jf; 261 continue; 262 263 case BPF_JMP|BPF_JGE|BPF_K: 264 pc += (A >= pc->k) ? pc->jt : pc->jf; 265 continue; 266 267 case BPF_JMP|BPF_JEQ|BPF_K: 268 pc += (A == pc->k) ? pc->jt : pc->jf; 269 continue; 270 271 case BPF_JMP|BPF_JSET|BPF_K: 272 pc += (A & pc->k) ? pc->jt : pc->jf; 273 continue; 274 275 case BPF_JMP|BPF_JGT|BPF_X: 276 pc += (A > X) ? pc->jt : pc->jf; 277 continue; 278 279 case BPF_JMP|BPF_JGE|BPF_X: 280 pc += (A >= X) ? pc->jt : pc->jf; 281 continue; 282 283 case BPF_JMP|BPF_JEQ|BPF_X: 284 pc += (A == X) ? pc->jt : pc->jf; 285 continue; 286 287 case BPF_JMP|BPF_JSET|BPF_X: 288 pc += (A & X) ? pc->jt : pc->jf; 289 continue; 290 291 case BPF_ALU|BPF_ADD|BPF_X: 292 A += X; 293 continue; 294 295 case BPF_ALU|BPF_SUB|BPF_X: 296 A -= X; 297 continue; 298 299 case BPF_ALU|BPF_MUL|BPF_X: 300 A *= X; 301 continue; 302 303 case BPF_ALU|BPF_DIV|BPF_X: 304 if (X == 0) 305 return 0; 306 A /= X; 307 continue; 308 309 case BPF_ALU|BPF_AND|BPF_X: 310 A &= X; 311 continue; 312 313 case BPF_ALU|BPF_OR|BPF_X: 314 A |= X; 315 continue; 316 317 case BPF_ALU|BPF_LSH|BPF_X: 318 A <<= X; 319 continue; 320 321 case BPF_ALU|BPF_RSH|BPF_X: 322 A >>= X; 323 continue; 324 325 case BPF_ALU|BPF_ADD|BPF_K: 326 A += pc->k; 327 continue; 328 329 case BPF_ALU|BPF_SUB|BPF_K: 330 A -= pc->k; 331 continue; 332 333 case BPF_ALU|BPF_MUL|BPF_K: 334 A *= pc->k; 335 continue; 336 337 case BPF_ALU|BPF_DIV|BPF_K: 338 A /= pc->k; 339 continue; 340 341 case BPF_ALU|BPF_AND|BPF_K: 342 A &= pc->k; 343 continue; 344 345 case BPF_ALU|BPF_OR|BPF_K: 346 A |= pc->k; 347 continue; 348 349 case BPF_ALU|BPF_LSH|BPF_K: 350 A <<= pc->k; 351 continue; 352 353 case BPF_ALU|BPF_RSH|BPF_K: 354 A >>= pc->k; 355 continue; 356 357 case BPF_ALU|BPF_NEG: 358 A = -A; 359 continue; 360 361 case BPF_MISC|BPF_TAX: 362 X = A; 363 continue; 364 365 case BPF_MISC|BPF_TXA: 366 A = X; 367 continue; 368 } 369 } 370 } 371 372 #ifdef _KERNEL 373 /* 374 * Return true if the 'fcode' is a valid filter program. 375 * The constraints are that each jump be forward and to a valid 376 * code and memory operations use valid addresses. The code 377 * must terminate with either an accept or reject. 378 * 379 * The kernel needs to be able to verify an application's filter code. 380 * Otherwise, a bogus program could easily crash the system. 381 */ 382 int 383 bpf_validate(struct bpf_insn *f, int len) 384 { 385 u_int i, from; 386 struct bpf_insn *p; 387 388 if (len < 1 || len > BPF_MAXINSNS) 389 return 0; 390 391 for (i = 0; i < len; ++i) { 392 p = &f[i]; 393 switch (BPF_CLASS(p->code)) { 394 /* 395 * Check that memory operations use valid addresses. 396 */ 397 case BPF_LD: 398 case BPF_LDX: 399 switch (BPF_MODE(p->code)) { 400 case BPF_IMM: 401 break; 402 case BPF_ABS: 403 case BPF_IND: 404 case BPF_MSH: 405 /* 406 * More strict check with actual packet length 407 * is done runtime. 408 */ 409 if (p->k >= bpf_maxbufsize) 410 return 0; 411 break; 412 case BPF_MEM: 413 if (p->k >= BPF_MEMWORDS) 414 return 0; 415 break; 416 case BPF_LEN: 417 break; 418 default: 419 return 0; 420 } 421 break; 422 case BPF_ST: 423 case BPF_STX: 424 if (p->k >= BPF_MEMWORDS) 425 return 0; 426 break; 427 case BPF_ALU: 428 switch (BPF_OP(p->code)) { 429 case BPF_ADD: 430 case BPF_SUB: 431 case BPF_MUL: 432 case BPF_OR: 433 case BPF_AND: 434 case BPF_LSH: 435 case BPF_RSH: 436 case BPF_NEG: 437 break; 438 case BPF_DIV: 439 /* 440 * Check for constant division by 0. 441 */ 442 if (BPF_SRC(p->code) == BPF_K && p->k == 0) 443 return 0; 444 break; 445 default: 446 return 0; 447 } 448 break; 449 case BPF_JMP: 450 /* 451 * Check that jumps are forward, and within 452 * the code block. 453 */ 454 from = i + 1; 455 switch (BPF_OP(p->code)) { 456 case BPF_JA: 457 if (from + p->k < from || from + p->k >= len) 458 return 0; 459 break; 460 case BPF_JEQ: 461 case BPF_JGT: 462 case BPF_JGE: 463 case BPF_JSET: 464 if (from + p->jt >= len || from + p->jf >= len) 465 return 0; 466 break; 467 default: 468 return 0; 469 } 470 break; 471 case BPF_RET: 472 break; 473 case BPF_MISC: 474 break; 475 default: 476 return 0; 477 } 478 479 } 480 return BPF_CLASS(f[len - 1].code) == BPF_RET; 481 } 482 #endif 483