1 /* $OpenBSD: bpf_filter.c,v 1.29 2016/04/02 09:05:16 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/types.h> 42 #include <sys/time.h> 43 #ifndef _KERNEL 44 #include <stdlib.h> 45 #include <string.h> 46 #include "pcap.h" 47 #else 48 #include <sys/systm.h> 49 #endif 50 51 #include <sys/endian.h> 52 53 #ifdef _KERNEL 54 extern int bpf_maxbufsize; 55 #endif 56 57 #include <net/bpf.h> 58 59 struct bpf_mem { 60 const u_char *pkt; 61 u_int len; 62 }; 63 64 u_int32_t bpf_mem_ldw(const void *, u_int32_t, int *); 65 u_int32_t bpf_mem_ldh(const void *, u_int32_t, int *); 66 u_int32_t bpf_mem_ldb(const void *, u_int32_t, int *); 67 68 const struct bpf_ops bpf_mem_ops = { 69 bpf_mem_ldw, 70 bpf_mem_ldh, 71 bpf_mem_ldb, 72 }; 73 74 u_int32_t 75 bpf_mem_ldw(const void *mem, u_int32_t k, int *err) 76 { 77 const struct bpf_mem *bm = mem; 78 u_int32_t v; 79 80 *err = 1; 81 82 if (k + sizeof(v) > bm->len) 83 return (0); 84 85 memcpy(&v, bm->pkt + k, sizeof(v)); 86 87 *err = 0; 88 return ntohl(v); 89 } 90 91 u_int32_t 92 bpf_mem_ldh(const void *mem, u_int32_t k, int *err) 93 { 94 const struct bpf_mem *bm = mem; 95 u_int16_t v; 96 97 *err = 1; 98 99 if (k + sizeof(v) > bm->len) 100 return (0); 101 102 memcpy(&v, bm->pkt + k, sizeof(v)); 103 104 *err = 0; 105 return ntohs(v); 106 } 107 108 u_int32_t 109 bpf_mem_ldb(const void *mem, u_int32_t k, int *err) 110 { 111 const struct bpf_mem *bm = mem; 112 113 *err = 1; 114 115 if (k >= bm->len) 116 return (0); 117 118 *err = 0; 119 return bm->pkt[k]; 120 } 121 122 /* 123 * Execute the filter program starting at pc on the packet p 124 * wirelen is the length of the original packet 125 * buflen is the amount of data present 126 */ 127 u_int 128 bpf_filter(const struct bpf_insn *pc, const u_char *pkt, 129 u_int wirelen, u_int buflen) 130 { 131 struct bpf_mem bm; 132 133 bm.pkt = pkt; 134 bm.len = buflen; 135 136 return _bpf_filter(pc, &bpf_mem_ops, &bm, wirelen); 137 } 138 139 u_int 140 _bpf_filter(const struct bpf_insn *pc, const struct bpf_ops *ops, 141 const void *pkt, u_int wirelen) 142 { 143 u_int32_t A = 0, X = 0; 144 u_int32_t k; 145 int32_t mem[BPF_MEMWORDS]; 146 int err; 147 148 bzero(mem, sizeof(mem)); 149 150 if (pc == NULL) { 151 /* 152 * No filter means accept all. 153 */ 154 return (u_int)-1; 155 } 156 157 --pc; 158 while (1) { 159 ++pc; 160 switch (pc->code) { 161 162 default: 163 #ifdef _KERNEL 164 return 0; 165 #else 166 abort(); 167 #endif 168 case BPF_RET|BPF_K: 169 return (u_int)pc->k; 170 171 case BPF_RET|BPF_A: 172 return (u_int)A; 173 174 case BPF_LD|BPF_W|BPF_ABS: 175 A = ops->ldw(pkt, pc->k, &err); 176 if (err != 0) 177 return 0; 178 continue; 179 180 case BPF_LD|BPF_H|BPF_ABS: 181 A = ops->ldh(pkt, pc->k, &err); 182 if (err != 0) 183 return 0; 184 continue; 185 186 case BPF_LD|BPF_B|BPF_ABS: 187 A = ops->ldb(pkt, pc->k, &err); 188 if (err != 0) 189 return 0; 190 continue; 191 192 case BPF_LD|BPF_W|BPF_LEN: 193 A = wirelen; 194 continue; 195 196 case BPF_LDX|BPF_W|BPF_LEN: 197 X = wirelen; 198 continue; 199 200 case BPF_LD|BPF_W|BPF_IND: 201 k = X + pc->k; 202 A = ops->ldw(pkt, k, &err); 203 if (err != 0) 204 return 0; 205 continue; 206 207 case BPF_LD|BPF_H|BPF_IND: 208 k = X + pc->k; 209 A = ops->ldh(pkt, k, &err); 210 if (err != 0) 211 return 0; 212 continue; 213 214 case BPF_LD|BPF_B|BPF_IND: 215 k = X + pc->k; 216 A = ops->ldb(pkt, k, &err); 217 if (err != 0) 218 return 0; 219 continue; 220 221 case BPF_LDX|BPF_MSH|BPF_B: 222 X = ops->ldb(pkt, pc->k, &err); 223 if (err != 0) 224 return 0; 225 X &= 0xf; 226 X <<= 2; 227 continue; 228 229 case BPF_LD|BPF_IMM: 230 A = pc->k; 231 continue; 232 233 case BPF_LDX|BPF_IMM: 234 X = pc->k; 235 continue; 236 237 case BPF_LD|BPF_MEM: 238 A = mem[pc->k]; 239 continue; 240 241 case BPF_LDX|BPF_MEM: 242 X = mem[pc->k]; 243 continue; 244 245 case BPF_ST: 246 mem[pc->k] = A; 247 continue; 248 249 case BPF_STX: 250 mem[pc->k] = X; 251 continue; 252 253 case BPF_JMP|BPF_JA: 254 pc += pc->k; 255 continue; 256 257 case BPF_JMP|BPF_JGT|BPF_K: 258 pc += (A > pc->k) ? pc->jt : pc->jf; 259 continue; 260 261 case BPF_JMP|BPF_JGE|BPF_K: 262 pc += (A >= pc->k) ? pc->jt : pc->jf; 263 continue; 264 265 case BPF_JMP|BPF_JEQ|BPF_K: 266 pc += (A == pc->k) ? pc->jt : pc->jf; 267 continue; 268 269 case BPF_JMP|BPF_JSET|BPF_K: 270 pc += (A & pc->k) ? pc->jt : pc->jf; 271 continue; 272 273 case BPF_JMP|BPF_JGT|BPF_X: 274 pc += (A > X) ? pc->jt : pc->jf; 275 continue; 276 277 case BPF_JMP|BPF_JGE|BPF_X: 278 pc += (A >= X) ? pc->jt : pc->jf; 279 continue; 280 281 case BPF_JMP|BPF_JEQ|BPF_X: 282 pc += (A == X) ? pc->jt : pc->jf; 283 continue; 284 285 case BPF_JMP|BPF_JSET|BPF_X: 286 pc += (A & X) ? pc->jt : pc->jf; 287 continue; 288 289 case BPF_ALU|BPF_ADD|BPF_X: 290 A += X; 291 continue; 292 293 case BPF_ALU|BPF_SUB|BPF_X: 294 A -= X; 295 continue; 296 297 case BPF_ALU|BPF_MUL|BPF_X: 298 A *= X; 299 continue; 300 301 case BPF_ALU|BPF_DIV|BPF_X: 302 if (X == 0) 303 return 0; 304 A /= X; 305 continue; 306 307 case BPF_ALU|BPF_AND|BPF_X: 308 A &= X; 309 continue; 310 311 case BPF_ALU|BPF_OR|BPF_X: 312 A |= X; 313 continue; 314 315 case BPF_ALU|BPF_LSH|BPF_X: 316 A <<= X; 317 continue; 318 319 case BPF_ALU|BPF_RSH|BPF_X: 320 A >>= X; 321 continue; 322 323 case BPF_ALU|BPF_ADD|BPF_K: 324 A += pc->k; 325 continue; 326 327 case BPF_ALU|BPF_SUB|BPF_K: 328 A -= pc->k; 329 continue; 330 331 case BPF_ALU|BPF_MUL|BPF_K: 332 A *= pc->k; 333 continue; 334 335 case BPF_ALU|BPF_DIV|BPF_K: 336 A /= pc->k; 337 continue; 338 339 case BPF_ALU|BPF_AND|BPF_K: 340 A &= pc->k; 341 continue; 342 343 case BPF_ALU|BPF_OR|BPF_K: 344 A |= pc->k; 345 continue; 346 347 case BPF_ALU|BPF_LSH|BPF_K: 348 A <<= pc->k; 349 continue; 350 351 case BPF_ALU|BPF_RSH|BPF_K: 352 A >>= pc->k; 353 continue; 354 355 case BPF_ALU|BPF_NEG: 356 A = -A; 357 continue; 358 359 case BPF_MISC|BPF_TAX: 360 X = A; 361 continue; 362 363 case BPF_MISC|BPF_TXA: 364 A = X; 365 continue; 366 } 367 } 368 } 369 370 #ifdef _KERNEL 371 /* 372 * Return true if the 'fcode' is a valid filter program. 373 * The constraints are that each jump be forward and to a valid 374 * code and memory operations use valid addresses. The code 375 * must terminate with either an accept or reject. 376 * 377 * The kernel needs to be able to verify an application's filter code. 378 * Otherwise, a bogus program could easily crash the system. 379 */ 380 int 381 bpf_validate(struct bpf_insn *f, int len) 382 { 383 u_int i, from; 384 struct bpf_insn *p; 385 386 if (len < 1 || len > BPF_MAXINSNS) 387 return 0; 388 389 for (i = 0; i < len; ++i) { 390 p = &f[i]; 391 switch (BPF_CLASS(p->code)) { 392 /* 393 * Check that memory operations use valid addresses. 394 */ 395 case BPF_LD: 396 case BPF_LDX: 397 switch (BPF_MODE(p->code)) { 398 case BPF_IMM: 399 break; 400 case BPF_ABS: 401 case BPF_IND: 402 case BPF_MSH: 403 /* 404 * More strict check with actual packet length 405 * is done runtime. 406 */ 407 if (p->k >= bpf_maxbufsize) 408 return 0; 409 break; 410 case BPF_MEM: 411 if (p->k >= BPF_MEMWORDS) 412 return 0; 413 break; 414 case BPF_LEN: 415 break; 416 default: 417 return 0; 418 } 419 break; 420 case BPF_ST: 421 case BPF_STX: 422 if (p->k >= BPF_MEMWORDS) 423 return 0; 424 break; 425 case BPF_ALU: 426 switch (BPF_OP(p->code)) { 427 case BPF_ADD: 428 case BPF_SUB: 429 case BPF_MUL: 430 case BPF_OR: 431 case BPF_AND: 432 case BPF_LSH: 433 case BPF_RSH: 434 case BPF_NEG: 435 break; 436 case BPF_DIV: 437 /* 438 * Check for constant division by 0. 439 */ 440 if (BPF_SRC(p->code) == BPF_K && p->k == 0) 441 return 0; 442 break; 443 default: 444 return 0; 445 } 446 break; 447 case BPF_JMP: 448 /* 449 * Check that jumps are forward, and within 450 * the code block. 451 */ 452 from = i + 1; 453 switch (BPF_OP(p->code)) { 454 case BPF_JA: 455 if (from + p->k < from || from + p->k >= len) 456 return 0; 457 break; 458 case BPF_JEQ: 459 case BPF_JGT: 460 case BPF_JGE: 461 case BPF_JSET: 462 if (from + p->jt >= len || from + p->jf >= len) 463 return 0; 464 break; 465 default: 466 return 0; 467 } 468 break; 469 case BPF_RET: 470 break; 471 case BPF_MISC: 472 break; 473 default: 474 return 0; 475 } 476 477 } 478 return BPF_CLASS(f[len - 1].code) == BPF_RET; 479 } 480 #endif 481