bpf_filter.c (153881) | bpf_filter.c (161357) |
---|---|
1/* $FreeBSD: head/contrib/ipfilter/bpf_filter.c 153881 2005-12-30 11:52:26Z guido $ */ | 1/* $FreeBSD: head/contrib/ipfilter/bpf_filter.c 161357 2006-08-16 12:23:02Z guido $ */ |
2 3/*- 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from the Stanford/CMU enet packet filter, 8 * (net/enet.c) distributed as part of 4.3BSD, and code contributed 9 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence --- 27 unchanged lines hidden (view full) --- 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)bpf.c 7.5 (Berkeley) 7/15/91 41 */ 42 43#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL)) 44static const char rcsid[] = | 2 3/*- 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from the Stanford/CMU enet packet filter, 8 * (net/enet.c) distributed as part of 4.3BSD, and code contributed 9 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence --- 27 unchanged lines hidden (view full) --- 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)bpf.c 7.5 (Berkeley) 7/15/91 41 */ 42 43#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL)) 44static const char rcsid[] = |
45 "@(#) $Header: /devel/CVS/IP-Filter/bpf_filter.c,v 2.2.2.1 2005/06/18 02:41:30 darrenr Exp $ (LBL)"; | 45 "@(#) $Header: /devel/CVS/IP-Filter/bpf_filter.c,v 2.2.2.2 2005/12/30 12:57:28 darrenr Exp $ (LBL)"; |
46#endif 47 48#include <sys/param.h> 49#include <sys/types.h> 50#include <sys/time.h> 51#include <sys/socket.h> 52 53#include <netinet/in.h> --- 409 unchanged lines hidden (view full) --- 463 } 464 } 465} 466 467 468/* 469 * Return true if the 'fcode' is a valid filter program. 470 * The constraints are that each jump be forward and to a valid | 46#endif 47 48#include <sys/param.h> 49#include <sys/types.h> 50#include <sys/time.h> 51#include <sys/socket.h> 52 53#include <netinet/in.h> --- 409 unchanged lines hidden (view full) --- 463 } 464 } 465} 466 467 468/* 469 * Return true if the 'fcode' is a valid filter program. 470 * The constraints are that each jump be forward and to a valid |
471 * code. The code must terminate with either an accept or reject. 472 * 'valid' is an array for use by the routine (it must be at least 473 * 'len' bytes long). | 471 * code, that memory accesses are within valid ranges (to the 472 * extent that this can be checked statically; loads of packet 473 * data have to be, and are, also checked at run time), and that 474 * the code terminates with either an accept or reject. |
474 * 475 * The kernel needs to be able to verify an application's filter code. 476 * Otherwise, a bogus program could easily crash the system. 477 */ 478int 479bpf_validate(f, len) 480 struct bpf_insn *f; 481 int len; 482{ | 475 * 476 * The kernel needs to be able to verify an application's filter code. 477 * Otherwise, a bogus program could easily crash the system. 478 */ 479int 480bpf_validate(f, len) 481 struct bpf_insn *f; 482 int len; 483{ |
483 register int i; 484 register struct bpf_insn *p; | 484 u_int i, from; 485 const struct bpf_insn *p; |
485 | 486 |
487 if (len == 0) 488 return 1; 489 490 if (len < 1 || len > BPF_MAXINSNS) 491 return 0; 492 |
|
486 for (i = 0; i < len; ++i) { | 493 for (i = 0; i < len; ++i) { |
494 p = &f[i]; 495 switch (BPF_CLASS(p->code)) { |
|
487 /* | 496 /* |
488 * Check that that jumps are forward, and within 489 * the code block. | 497 * Check that memory operations use valid addresses. |
490 */ | 498 */ |
491 p = &f[i]; 492 if (BPF_CLASS(p->code) == BPF_JMP) { 493 register int from = i + 1; 494 495 if (BPF_OP(p->code) == BPF_JA) { 496 if (from + p->k >= (unsigned)len) | 499 case BPF_LD: 500 case BPF_LDX: 501 switch (BPF_MODE(p->code)) { 502 case BPF_IMM: 503 break; 504 case BPF_ABS: 505 case BPF_IND: 506 case BPF_MSH: 507 /* 508 * More strict check with actual packet length 509 * is done runtime. 510 */ 511#if 0 512 if (p->k >= bpf_maxbufsize) |
497 return 0; | 513 return 0; |
514#endif 515 break; 516 case BPF_MEM: 517 if (p->k >= BPF_MEMWORDS) 518 return 0; 519 break; 520 case BPF_LEN: 521 break; 522 default: 523 return 0; |
|
498 } | 524 } |
499 else if (from + p->jt >= len || from + p->jf >= len) | 525 break; 526 case BPF_ST: 527 case BPF_STX: 528 if (p->k >= BPF_MEMWORDS) |
500 return 0; | 529 return 0; |
501 } 502 /* 503 * Check that memory operations use valid addresses. 504 */ 505 if ((BPF_CLASS(p->code) == BPF_ST || 506 (BPF_CLASS(p->code) == BPF_LD && 507 (p->code & 0xe0) == BPF_MEM)) && 508 (p->k >= BPF_MEMWORDS || p->k < 0)) | 530 break; 531 case BPF_ALU: 532 switch (BPF_OP(p->code)) { 533 case BPF_ADD: 534 case BPF_SUB: 535 case BPF_OR: 536 case BPF_AND: 537 case BPF_LSH: 538 case BPF_RSH: 539 case BPF_NEG: 540 break; 541 case BPF_DIV: 542 /* 543 * Check for constant division by 0. 544 */ 545 if (BPF_RVAL(p->code) == BPF_K && p->k == 0) 546 return 0; 547 default: 548 return 0; 549 } 550 break; 551 case BPF_JMP: 552 /* 553 * Check that jumps are within the code block, 554 * and that unconditional branches don't go 555 * backwards as a result of an overflow. 556 * Unconditional branches have a 32-bit offset, 557 * so they could overflow; we check to make 558 * sure they don't. Conditional branches have 559 * an 8-bit offset, and the from address is <= 560 * BPF_MAXINSNS, and we assume that BPF_MAXINSNS 561 * is sufficiently small that adding 255 to it 562 * won't overflow. 563 * 564 * We know that len is <= BPF_MAXINSNS, and we 565 * assume that BPF_MAXINSNS is < the maximum size 566 * of a u_int, so that i + 1 doesn't overflow. 567 */ 568 from = i + 1; 569 switch (BPF_OP(p->code)) { 570 case BPF_JA: 571 if (from + p->k < from || from + p->k >= len) 572 return 0; 573 break; 574 case BPF_JEQ: 575 case BPF_JGT: 576 case BPF_JGE: 577 case BPF_JSET: 578 if (from + p->jt >= len || from + p->jf >= len) 579 return 0; 580 break; 581 default: 582 return 0; 583 } 584 break; 585 case BPF_RET: 586 break; 587 case BPF_MISC: 588 break; 589 default: |
509 return 0; | 590 return 0; |
510 /* 511 * Check for constant division by 0. 512 */ 513 if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) 514 return 0; | 591 } |
515 } 516 return BPF_CLASS(f[len - 1].code) == BPF_RET; 517} | 592 } 593 return BPF_CLASS(f[len - 1].code) == BPF_RET; 594} |