Deleted Added
full compact
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}