svn commit: r236231 - head/sys/net

Alexander V. Chernikov melifaro at FreeBSD.org
Tue May 29 12:52:31 UTC 2012


Author: melifaro
Date: Tue May 29 12:52:30 2012
New Revision: 236231
URL: http://svn.freebsd.org/changeset/base/236231

Log:
  Fix BPF_JITTER code broken by r235746.
  
  Pointed by:       jkim
  Reviewed by:      jkim (except locking changes)
  Approved by:      (mentor)
  MFC after:        2 weeks

Modified:
  head/sys/net/bpf.c

Modified: head/sys/net/bpf.c
==============================================================================
--- head/sys/net/bpf.c	Tue May 29 12:33:09 2012	(r236230)
+++ head/sys/net/bpf.c	Tue May 29 12:52:30 2012	(r236231)
@@ -1711,7 +1711,7 @@ bpf_setf(struct bpf_d *d, struct bpf_pro
 	struct bpf_insn *fcode, *old;
 	u_int wfilter, flen, size;
 #ifdef BPF_JITTER
-	bpf_jit_filter *ofunc, *jfunc;
+	bpf_jit_filter *jfunc, *ofunc;
 #endif
 	int need_upgrade;
 #ifdef COMPAT_FREEBSD32
@@ -1737,13 +1737,20 @@ bpf_setf(struct bpf_d *d, struct bpf_pro
 
 	need_upgrade = 0;
 	size = flen * sizeof(*fp->bf_insns);
-	if (size > 0)
+	if (size > 0) {
+		/* We're setting up new filter. Copy and check actual data */
 		fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK);
-	else
+		if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) != 0 ||
+		    bpf_validate(fcode, (int)flen) == 0) {
+			free(fcode, M_BPF);
+			return (EINVAL);
+		}
+		/* Filter is copied inside fcode and is perfectly valid */
+	} else
 		fcode = NULL; /* Make compiler happy */
 
 #ifdef BPF_JITTER
-	if (fp->bf_insns != NULL)
+	if (fcode != NULL)
 		jfunc = bpf_jitter(fcode, flen);
 	else
 		jfunc = NULL; /* Make compiler happy */
@@ -1764,7 +1771,7 @@ bpf_setf(struct bpf_d *d, struct bpf_pro
 		ofunc = d->bd_bfilter;
 #endif
 	}
-	if (fp->bf_insns == NULL) {
+	if (fcode == NULL) {
 		/* 
 		 * Protect filter removal by interface lock.
 		 * Additionally, we are protected by global lock here.
@@ -1795,55 +1802,50 @@ bpf_setf(struct bpf_d *d, struct bpf_pro
 		return (0);
 	}
 
-	if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
-	    bpf_validate(fcode, (int)flen)) {
-		/* 
-		 * Protect filter change by interface lock
-		 * Additionally, we are protected by global lock here.
-		 */
-		if (d->bd_bif != NULL)
-			BPFIF_WLOCK(d->bd_bif);
-		BPFD_LOCK(d);
-		if (wfilter)
-			d->bd_wfilter = fcode;
-		else {
-			d->bd_rfilter = fcode;
+	/* 
+	 * Set up new filter.
+	 * Protect filter change by interface lock
+	 * Additionally, we are protected by global lock here.
+	 */
+	if (d->bd_bif != NULL)
+		BPFIF_WLOCK(d->bd_bif);
+	BPFD_LOCK(d);
+	if (wfilter)
+		d->bd_wfilter = fcode;
+	else {
+		d->bd_rfilter = fcode;
 #ifdef BPF_JITTER
-			d->bd_bfilter = jfunc;
+		d->bd_bfilter = jfunc;
 #endif
-			if (cmd == BIOCSETF)
-				reset_d(d);
+		if (cmd == BIOCSETF)
+			reset_d(d);
 
-			/*
-			 * Do not require upgrade by first BIOCSETF
-			 * (used to set snaplen) by pcap_open_live()
-			 */
-			if ((d->bd_writer != 0) && (--d->bd_writer == 0))
-				need_upgrade = 1;
-			CTR4(KTR_NET, "%s: filter function set by pid %d, "
-			    "bd_writer counter %d, need_upgrade %d",
-			    __func__, d->bd_pid, d->bd_writer, need_upgrade);
-		}
-		BPFD_UNLOCK(d);
-		if (d->bd_bif != NULL)
-			BPFIF_WUNLOCK(d->bd_bif);
-		if (old != NULL)
-			free((caddr_t)old, M_BPF);
+		/*
+		 * Do not require upgrade by first BIOCSETF
+		 * (used to set snaplen) by pcap_open_live()
+		 */
+		if ((d->bd_writer != 0) && (--d->bd_writer == 0))
+			need_upgrade = 1;
+		CTR4(KTR_NET, "%s: filter function set by pid %d, "
+		    "bd_writer counter %d, need_upgrade %d",
+		    __func__, d->bd_pid, d->bd_writer, need_upgrade);
+	}
+	BPFD_UNLOCK(d);
+	if (d->bd_bif != NULL)
+		BPFIF_WUNLOCK(d->bd_bif);
+	if (old != NULL)
+		free((caddr_t)old, M_BPF);
 #ifdef BPF_JITTER
-		if (ofunc != NULL)
-			bpf_destroy_jit_filter(ofunc);
+	if (ofunc != NULL)
+		bpf_destroy_jit_filter(ofunc);
 #endif
 
-		/* Move d to active readers list */
-		if (need_upgrade != 0)
-			bpf_upgraded(d);
+	/* Move d to active readers list */
+	if (need_upgrade != 0)
+		bpf_upgraded(d);
 
-		BPF_UNLOCK();
-		return (0);
-	}
-	free((caddr_t)fcode, M_BPF);
 	BPF_UNLOCK();
-	return (EINVAL);
+	return (0);
 }
 
 /*


More information about the svn-src-all mailing list