From nobody@FreeBSD.org  Wed Nov 30 10:11:41 2005
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 2649C16A41F
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 30 Nov 2005 10:11:41 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id B442D43D49
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 30 Nov 2005 10:11:40 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id jAUABeu4079723
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 30 Nov 2005 10:11:40 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id jAUABd8F079721;
	Wed, 30 Nov 2005 10:11:39 GMT
	(envelope-from nobody)
Message-Id: <200511301011.jAUABd8F079721@www.freebsd.org>
Date: Wed, 30 Nov 2005 10:11:39 GMT
From: Guy Harris <guy@alum.mit.edu>
To: freebsd-gnats-submit@FreeBSD.org
Subject: bpf_validate() needs to do more checks
X-Send-Pr-Version: www-2.3

>Number:         89752
>Category:       kern
>Synopsis:       [bpf] [patch] bpf_validate() needs to do more checks
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Nov 30 10:20:02 GMT 2005
>Closed-Date:    Tue Nov 13 20:45:40 UTC 2012
>Last-Modified:  Tue Nov 13 20:45:40 UTC 2012
>Originator:     Guy Harris
>Release:        
>Organization:
>Environment:
>Description:
OpenBSD's bpf_validate() in sys/net/bpf_filter.c does some additional checks to catch:

        BPF programs with no instructions or with more than BPF_MAXINSNS instructions;

        BPF_STX and BPF_LDX|BPF_MEM instructions that have out-of-range offsets (which could be made to fetch or store into arbitrary memory locations);

        BPF_DIV instructions with a constant 0 divisor (that's a check also done at run time).

Here's a patch to make the FreeBSD bpf_validate() match it (with some changes to comments; I've submitted the changes to comments to the OpenBSD bug database).

        
>How-To-Repeat:
              
>Fix:
Index: bpf_filter.c
===================================================================
RCS file: /home/ncvs/src/sys/net/bpf_filter.c,v
retrieving revision 1.23
diff -c -r1.23 bpf_filter.c
*** bpf_filter.c	7 Jan 2005 01:45:34 -0000	1.23
--- bpf_filter.c	30 Nov 2005 09:57:08 -0000
***************
*** 507,513 ****
  /*
   * Return true if the 'fcode' is a valid filter program.
   * The constraints are that each jump be forward and to a valid
!  * code.  The code must terminate with either an accept or reject.
   *
   * The kernel needs to be able to verify an application's filter code.
   * Otherwise, a bogus program could easily crash the system.
--- 507,516 ----
  /*
   * Return true if the 'fcode' is a valid filter program.
   * The constraints are that each jump be forward and to a valid
!  * code, that memory accesses are within valid ranges (to the
!  * extent that this can be checked statically; loads of packet
!  * data have to be, and are, also checked at run time), and that
!  * the code terminates with either an accept or reject.
   *
   * The kernel needs to be able to verify an application's filter code.
   * Otherwise, a bogus program could easily crash the system.
***************
*** 517,555 ****
  	const struct bpf_insn *f;
  	int len;
  {
! 	register int i;
  	register const struct bpf_insn *p;
  
  	for (i = 0; i < len; ++i) {
  		/*
! 		 * Check that that jumps are forward, and within
! 		 * the code block.
  		 */
! 		p = &f[i];
! 		if (BPF_CLASS(p->code) == BPF_JMP) {
! 			register int from = i + 1;
! 
! 			if (BPF_OP(p->code) == BPF_JA) {
! 				if (from >= len || p->k >= len - from)
  					return 0;
  			}
! 			else if (from >= len || p->jt >= len - from ||
! 				 p->jf >= len - from)
  				return 0;
! 		}
! 		/*
! 		 * Check that memory operations use valid addresses.
! 		 */
! 		if ((BPF_CLASS(p->code) == BPF_ST ||
! 		     (BPF_CLASS(p->code) == BPF_LD &&
! 		      (p->code & 0xe0) == BPF_MEM)) &&
! 		    p->k >= BPF_MEMWORDS)
! 			return 0;
! 		/*
! 		 * Check for constant division by 0.
! 		 */
! 		if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
  			return 0;
  	}
  	return BPF_CLASS(f[len - 1].code) == BPF_RET;
  }
--- 520,628 ----
  	const struct bpf_insn *f;
  	int len;
  {
! 	u_int i, from;
  	register const struct bpf_insn *p;
  
+ 	if (len < 1 || len > BPF_MAXINSNS)
+ 		return 0;
+ 
  	for (i = 0; i < len; ++i) {
+ 		p = &f[i];
+ 		switch (BPF_CLASS(p->code)) {
  		/*
! 		 * Check that memory operations use valid addresses.
  		 */
! 		case BPF_LD:
! 		case BPF_LDX:
! 			switch (BPF_MODE(p->code)) {
! 			case BPF_IMM:
! 				break;
! 			case BPF_ABS:
! 			case BPF_IND:
! 			case BPF_MSH:
! 				/*
! 				 * More strict check with actual packet length
! 				 * is done runtime.
! 				 */
! 				if (p->k >= bpf_maxbufsize)
! 					return 0;
! 				break;
! 			case BPF_MEM:
! 				if (p->k >= BPF_MEMWORDS)
  					return 0;
+ 				break;
+ 			case BPF_LEN:
+ 				break;
+ 			default:
+ 				return 0;
  			}
! 			break;
! 		case BPF_ST:
! 		case BPF_STX:
! 			if (p->k >= BPF_MEMWORDS)
  				return 0;
! 			break;
! 		case BPF_ALU:
! 			switch (BPF_OP(p->code)) {
! 			case BPF_ADD:
! 			case BPF_SUB:
! 			case BPF_OR:
! 			case BPF_AND:
! 			case BPF_LSH:
! 			case BPF_RSH:
! 			case BPF_NEG:
! 				break;
! 			case BPF_DIV:
! 				/*
! 				 * Check for constant division by 0.
! 				 */
! 				if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
! 					return 0;
! 			default:
! 				return 0;
! 			}
! 			break;
! 		case BPF_JMP:
! 			/*
! 			 * Check that jumps are within the code block,
! 			 * and that unconditional branches don't go
! 			 * backwards as a result of an overflow.
! 			 * Unconditional branches have a 32-bit offset,
! 			 * so they could overflow; we check to make
! 			 * sure they don't.  Conditional branches have
! 			 * an 8-bit offset, and the from address is <=
! 			 * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
! 			 * is sufficiently small that adding 255 to it
! 			 * won't overflow.
! 			 *
! 			 * We know that len is <= BPF_MAXINSNS, and we
! 			 * assume that BPF_MAXINSNS is < the maximum size
! 			 * of a u_int, so that i + 1 doesn't overflow.
! 			 */
! 			from = i + 1;
! 			switch (BPF_OP(p->code)) {
! 			case BPF_JA:
! 				if (from + p->k < from || from + p->k >= len)
! 					return 0;
! 				break;
! 			case BPF_JEQ:
! 			case BPF_JGT:
! 			case BPF_JGE:
! 			case BPF_JSET:
! 				if (from + p->jt >= len || from + p->jf >= len)
! 					return 0;
! 				break;
! 			default:
! 				return 0;
! 			}
! 			break;
! 		case BPF_RET:
! 			break;
! 		case BPF_MISC:
! 			break;
! 		default:
  			return 0;
+ 		}
  	}
  	return BPF_CLASS(f[len - 1].code) == BPF_RET;
  }

>Release-Note:
>Audit-Trail:

From: Guy Harris <guy@alum.mit.edu>
To: bug-followup@FreeBSD.org, guy@alum.mit.edu
Cc:  
Subject: Re: kern/89752: bpf_validate() needs to do more checks
Date: Wed, 30 Nov 2005 03:25:22 -0800

 This is a multi-part message in MIME format.
 --------------030206000405030002050805
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 I've attached a unified diff for the patch, just in case the patch got 
 tabs mangled to spaces (I submitted the bug via the Web).
 
 --------------030206000405030002050805
 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
  name="patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="patch"
 
 Index: bpf_filter.c
 ===================================================================
 RCS file: /cvs/root/System/xnu/bsd/net/bpf_filter.c,v
 retrieving revision 1.8
 diff -u -r1.8 bpf_filter.c
 --- bpf_filter.c	2004/04/01 23:28:48	1.8
 +++ bpf_filter.c	2005/11/30 11:23:17
 @@ -522,9 +522,10 @@
  /*
   * Return true if the 'fcode' is a valid filter program.
   * The constraints are that each jump be forward and to a valid
 - * code.  The code must terminate with either an accept or reject.
 - * 'valid' is an array for use by the routine (it must be at least
 - * 'len' bytes long).
 + * code, that memory accesses are within valid ranges (to the
 + * extent that this can be checked statically; loads of packet
 + * data have to be, and are, also checked at run time), and that
 + * the code terminates with either an accept or reject.
   *
   * The kernel needs to be able to verify an application's filter code.
   * Otherwise, a bogus program could easily crash the system.
 @@ -532,39 +533,109 @@
  int
  bpf_validate(const struct bpf_insn *f, int len)
  {
 -	register int i;
 +	u_int i, from;
  	const struct bpf_insn *p;
  
 +	if (len < 1 || len > BPF_MAXINSNS)
 +		return 0;
 +
  	for (i = 0; i < len; ++i) {
 +		p = &f[i];
 +		switch (BPF_CLASS(p->code)) {
  		/*
 -		 * Check that that jumps are forward, and within
 -		 * the code block.
 +		 * Check that memory operations use valid addresses.
  		 */
 -		p = &f[i];
 -		if (BPF_CLASS(p->code) == BPF_JMP) {
 -			register int from = i + 1;
 -
 -			if (BPF_OP(p->code) == BPF_JA) {
 -				if (from >= len || p->k >= (bpf_u_int32)(len - from))
 +		case BPF_LD:
 +		case BPF_LDX:
 +			switch (BPF_MODE(p->code)) {
 +			case BPF_IMM:
 +				break;
 +			case BPF_ABS:
 +			case BPF_IND:
 +			case BPF_MSH:
 +				/*
 +				 * More strict check with actual packet length
 +				 * is done runtime.
 +				 */
 +				if (p->k >= bpf_maxbufsize)
 +					return 0;
 +				break;
 +			case BPF_MEM:
 +				if (p->k >= BPF_MEMWORDS)
  					return 0;
 +				break;
 +			case BPF_LEN:
 +				break;
 +			default:
 +				return 0;
  			}
 -			else if (from >= len || p->jt >= len - from ||
 -				 p->jf >= len - from)
 +			break;
 +		case BPF_ST:
 +		case BPF_STX:
 +			if (p->k >= BPF_MEMWORDS)
  				return 0;
 -		}
 -		/*
 -		 * Check that memory operations use valid addresses.
 -		 */
 -		if ((BPF_CLASS(p->code) == BPF_ST ||
 -		     (BPF_CLASS(p->code) == BPF_LD &&
 -		      (p->code & 0xe0) == BPF_MEM)) &&
 -		    p->k >= BPF_MEMWORDS)
 -			return 0;
 -		/*
 -		 * Check for constant division by 0.
 -		 */
 -		if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
 +			break;
 +		case BPF_ALU:
 +			switch (BPF_OP(p->code)) {
 +			case BPF_ADD:
 +			case BPF_SUB:
 +			case BPF_OR:
 +			case BPF_AND:
 +			case BPF_LSH:
 +			case BPF_RSH:
 +			case BPF_NEG:
 +				break;
 +			case BPF_DIV:
 +				/*
 +				 * Check for constant division by 0.
 +				 */
 +				if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
 +					return 0;
 +			default:
 +				return 0;
 +			}
 +			break;
 +		case BPF_JMP:
 +			/*
 +			 * Check that jumps are within the code block,
 +			 * and that unconditional branches don't go
 +			 * backwards as a result of an overflow.
 +			 * Unconditional branches have a 32-bit offset,
 +			 * so they could overflow; we check to make
 +			 * sure they don't.  Conditional branches have
 +			 * an 8-bit offset, and the from address is <=
 +			 * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
 +			 * is sufficiently small that adding 255 to it
 +			 * won't overflow.
 +			 *
 +			 * We know that len is <= BPF_MAXINSNS, and we
 +			 * assume that BPF_MAXINSNS is < the maximum size
 +			 * of a u_int, so that i + 1 doesn't overflow.
 +			 */
 +			from = i + 1;
 +			switch (BPF_OP(p->code)) {
 +			case BPF_JA:
 +				if (from + p->k < from || from + p->k >= len)
 +					return 0;
 +				break;
 +			case BPF_JEQ:
 +			case BPF_JGT:
 +			case BPF_JGE:
 +			case BPF_JSET:
 +				if (from + p->jt >= len || from + p->jf >= len)
 +					return 0;
 +				break;
 +			default:
 +				return 0;
 +			}
 +			break;
 +		case BPF_RET:
 +			break;
 +		case BPF_MISC:
 +			break;
 +		default:
  			return 0;
 +		}
  	}
  	return BPF_CLASS(f[len - 1].code) == BPF_RET;
  }
 
 --------------030206000405030002050805--

From: Jung-uk Kim <jkim@FreeBSD.org>
To: bug-followup@FreeBSD.org, guy@alum.mit.edu
Cc:  
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Wed, 7 Dec 2005 17:32:31 -0500

 It looks good but `bpf_maxbufsize' may be unavailable to other 
 consumers such as ng_bpf(4) and it doesn't make sense to them.

From: Guy Harris <guy@alum.mit.edu>
To: Jung-uk Kim <jkim@FreeBSD.org>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Wed, 7 Dec 2005 15:11:03 -0800

 On Dec 7, 2005, at 2:32 PM, Jung-uk Kim wrote:
 
 > It looks good but `bpf_maxbufsize' may be unavailable to other
 > consumers such as ng_bpf(4) and it doesn't make sense to them.
 
 Then that check can probably be removed - OpenBSD's consumers might  
 all use bpf_maxbufsize, so it was OK for them, and it's just an  
 optimization anyway (as the comment says, a "More strict check with  
 actual packet length is done runtime").
 
 (BTW, this was from OpenBSD; if you check it in, say it's from Otto  
 Moerbeek's changes to OpenBSD, do *NOT* give me direct credit for it!)

From: Jung-uk Kim <jkim@FreeBSD.org>
To: Guy Harris <guy@alum.mit.edu>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Wed, 7 Dec 2005 18:37:59 -0500

 On Wednesday 07 December 2005 06:11 pm, Guy Harris wrote:
 > On Dec 7, 2005, at 2:32 PM, Jung-uk Kim wrote:
 > > It looks good but `bpf_maxbufsize' may be unavailable to other
 > > consumers such as ng_bpf(4) and it doesn't make sense to them.
 >
 > Then that check can probably be removed - OpenBSD's consumers might
 > all use bpf_maxbufsize, so it was OK for them, and it's just an
 > optimization anyway (as the comment says, a "More strict check with
 > actual packet length is done runtime").
 
 I found another problem.  BPF_MAXINSNS is tunable in FreeBSD and it is 
 not available to use for others.  If we remove the check also, 
 there's no difference from the previous implementation. :-(
 
 > (BTW, this was from OpenBSD; if you check it in, say it's from Otto
 > Moerbeek's changes to OpenBSD, do *NOT* give me direct credit for
 > it!)
 
 Thanks for letting us know.
 
 Jung-uk Kim

From: Jung-uk Kim <jkim@FreeBSD.org>
To: Guy Harris <guy@alum.mit.edu>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Wed, 7 Dec 2005 19:07:53 -0500

 On Wednesday 07 December 2005 06:37 pm, Jung-uk Kim wrote:
 > I found another problem.  BPF_MAXINSNS is tunable in FreeBSD and it
 > is not available to use for others.  If we remove the check also,
 > there's no difference from the previous implementation. :-(
 
 The only usable change for FreeBSD was this:
 
 http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/net/bpf_filter.c.diff?r1=1.23&r2=1.24
 
 Is this okay for you?
 
 Thanks,
 
 Jung-uk Kim

From: Guy Harris <guy@alum.mit.edu>
To: Jung-uk Kim <jkim@FreeBSD.org>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Wed, 7 Dec 2005 17:15:28 -0800

 On Dec 7, 2005, at 3:37 PM, Jung-uk Kim wrote:
 
 > I found another problem.  BPF_MAXINSNS is tunable in FreeBSD and it is
 > not available to use for others.  If we remove the check also,
 > there's no difference from the previous implementation. :-(
 
 What about the change to ensure that it checks both BPF_LD *and*  
 BPF_LDX, and both BPF_ST *and* BPF_STX?
 
Responsible-Changed-From-To: freebsd-bugs->csjp 
Responsible-Changed-By: kmacy 
Responsible-Changed-When: Fri Nov 16 01:55:50 UTC 2007 
Responsible-Changed-Why:  

Assign to acting maintainer. It is never wise to blow off Guy. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=89752 

From: Guy Harris <guy@alum.mit.edu>
To: bug-followup@FreeBSD.org, guy@alum.mit.edu
Cc:  
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Tue, 01 Jan 2008 18:01:13 -0800

 This is a multi-part message in MIME format.
 --------------000508080004080703000806
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Here's an updated patch, which fixes some problems with multiply and 
 divide instructions (it wasn't allowing them).
 
 --------------000508080004080703000806
 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
  name="patch-3"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="patch-3"
 
 Index: bpf_filter.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/net/bpf_filter.c,v
 retrieving revision 1.29
 diff -u -r1.29 bpf_filter.c
 --- bpf_filter.c	25 Dec 2007 13:24:02 -0000	1.29
 +++ bpf_filter.c	2 Jan 2008 02:00:07 -0000
 @@ -508,7 +508,10 @@
  /*
   * Return true if the 'fcode' is a valid filter program.
   * The constraints are that each jump be forward and to a valid
 - * code.  The code must terminate with either an accept or reject.
 + * code, that memory accesses are within valid ranges (to the
 + * extent that this can be checked statically; loads of packet
 + * data have to be, and are, also checked at run time), and that
 + * the code terminates with either an accept or reject.
   *
   * The kernel needs to be able to verify an application's filter code.
   * Otherwise, a bogus program could easily crash the system.
 @@ -518,7 +521,7 @@
  	const struct bpf_insn *f;
  	int len;
  {
 -	register int i;
 +	u_int i, from;
  	register const struct bpf_insn *p;
  
  	/* Do not accept negative length filter. */
 @@ -530,35 +533,97 @@
  		return 1;
  
  	for (i = 0; i < len; ++i) {
 +		p = &f[i];
 +		switch (BPF_CLASS(p->code)) {
  		/*
 -		 * Check that that jumps are forward, and within
 -		 * the code block.
 +		 * Check that memory operations use valid addresses.
  		 */
 -		p = &f[i];
 -		if (BPF_CLASS(p->code) == BPF_JMP) {
 -			register int from = i + 1;
 -
 -			if (BPF_OP(p->code) == BPF_JA) {
 -				if (from >= len || p->k >= len - from)
 +		case BPF_LD:
 +		case BPF_LDX:
 +			switch (BPF_MODE(p->code)) {
 +			case BPF_IMM:
 +				break;
 +			case BPF_ABS:
 +			case BPF_IND:
 +			case BPF_MSH:
 +				break;
 +			case BPF_MEM:
 +				if (p->k >= BPF_MEMWORDS)
  					return 0;
 +				break;
 +			case BPF_LEN:
 +				break;
 +			default:
 +				return 0;
  			}
 -			else if (from >= len || p->jt >= len - from ||
 -				 p->jf >= len - from)
 +			break;
 +		case BPF_ST:
 +		case BPF_STX:
 +			if (p->k >= BPF_MEMWORDS)
  				return 0;
 -		}
 -		/*
 -		 * Check that memory operations use valid addresses.
 -		 */
 -		if ((BPF_CLASS(p->code) == BPF_ST ||
 -		     (BPF_CLASS(p->code) == BPF_LD &&
 -		      (p->code & 0xe0) == BPF_MEM)) &&
 -		    p->k >= BPF_MEMWORDS)
 -			return 0;
 -		/*
 -		 * Check for constant division by 0.
 -		 */
 -		if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
 +			break;
 +		case BPF_ALU:
 +			switch (BPF_OP(p->code)) {
 +			case BPF_ADD:
 +			case BPF_SUB:
 +			case BPF_MUL:
 +			case BPF_OR:
 +			case BPF_AND:
 +			case BPF_LSH:
 +			case BPF_RSH:
 +			case BPF_NEG:
 +				break;
 +			case BPF_DIV:
 +				/*
 +				 * Check for constant division by 0.
 +				 */
 +				if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
 +					return 0;
 +				break;
 +			default:
 +				return 0;
 +			}
 +			break;
 +		case BPF_JMP:
 +			/*
 +			 * Check that jumps are within the code block,
 +			 * and that unconditional branches don't go
 +			 * backwards as a result of an overflow.
 +			 * Unconditional branches have a 32-bit offset,
 +			 * so they could overflow; we check to make
 +			 * sure they don't.  Conditional branches have
 +			 * an 8-bit offset, and the from address is <=
 +			 * len, and we assume that len is sufficiently
 +			 * small that adding 255 to it won't overflow.
 +			 *
 +			 * We also know that i < len, and assume that len
 +			 * is sufficiently small that i + 1 doesn't
 +			 * overflow.
 +			 */
 +			from = i + 1;
 +			switch (BPF_OP(p->code)) {
 +			case BPF_JA:
 +				if (from + p->k < from || from + p->k >= len)
 +					return 0;
 +				break;
 +			case BPF_JEQ:
 +			case BPF_JGT:
 +			case BPF_JGE:
 +			case BPF_JSET:
 +				if (from + p->jt >= len || from + p->jf >= len)
 +					return 0;
 +				break;
 +			default:
 +				return 0;
 +			}
 +			break;
 +		case BPF_RET:
 +			break;
 +		case BPF_MISC:
 +			break;
 +		default:
  			return 0;
 +		}
  	}
  	return BPF_CLASS(f[len - 1].code) == BPF_RET;
  }
 
 --------------000508080004080703000806--
Responsible-Changed-From-To: csjp->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Fri Feb 22 09:26:05 UTC 2008 
Responsible-Changed-Why:  
I'll try and take a look at it, as I've had a look at some other 
PRs in this area. If Christian wants to grab it back again, that's 
fine with me! 

David. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=89752 

From: Jung-uk Kim <jkim@FreeBSD.org>
To: bug-followup@FreeBSD.org
Cc: dwmalone@FreeBSD.org,
 guy@alum.mit.edu
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Thu, 28 Aug 2008 14:17:58 -0400

 FYI, the most critical bug is fixed:
 
 http://docs.freebsd.org/cgi/mid.cgi?200808281749.m7SHnr5W047153
 
 Sorry, it took so long.
 
 Jung-uk Kim

From: Jung-uk Kim <jkim@FreeBSD.org>
To: bug-followup@FreeBSD.org
Cc: dwmalone@FreeBSD.org,
 guy@alum.mit.edu
Subject: Re: kern/89752: [bpf] [patch] bpf_validate() needs to do more checks
Date: Thu, 28 Aug 2008 18:11:21 -0400

 Also, illegal codes are checked by the following commit:
 
 http://docs.freebsd.org/cgi/mid.cgi?200808282200.m7SM0bQq094145
 
 I used a bitmap instead of switch/cases, though. :-)
 
 Jung-uk Kim

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/89752: commit references a PR
Date: Fri, 29 Aug 2008 19:11:22 +0000 (UTC)

 jkim        2008-08-29 19:10:51 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/net              bpf_filter.c 
   Log:
   SVN rev 182454 on 2008-08-29 19:10:51Z by jkim
   
   - Directly match code wherever possible instead of using macros.
   - Macrofy bitmap table lookup.  Constify the table while I am here.
   - Add missing continue statements in the for loop.
   
   Functionally it should be the last remaining fix from:
   
   PR:             kern/89752
   MFC after:      1 month
   
   Revision  Changes    Path
   1.35      +14 -11    src/sys/net/bpf_filter.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->feedback 
State-Changed-By: linimon 
State-Changed-When: Sun Feb 1 01:35:11 UTC 2009 
State-Changed-Why:  
Over to committer.  dkim: does this need to be MFCed? 


Responsible-Changed-From-To: dwmalone->dkim 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Feb 1 01:35:11 UTC 2009 
Responsible-Changed-Why:  

http://www.freebsd.org/cgi/query-pr.cgi?pr=89752 
Responsible-Changed-From-To: dkim->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Sun Feb 1 09:15:15 UTC 2009 
Responsible-Changed-Why:  
Take this PR back, as we don't have a committer called dkim and I'm 
still interested in it. 

David. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=89752 
Responsible-Changed-From-To: dwmalone->freebsd-bugs 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Tue Jul 10 03:41:56 UTC 2012 
Responsible-Changed-Why:  
over to the pool (approved by bugmeister) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=89752 
State-Changed-From-To: feedback->closed 
State-Changed-By: eadler 
State-Changed-When: Tue Nov 13 20:45:39 UTC 2012 
State-Changed-Why:  
MFCed/fixed by now or it will never be MFCed 

http://www.freebsd.org/cgi/query-pr.cgi?pr=89752 
>Unformatted:
