Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jun 2012 12:10:12 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org
Subject:   svn commit: r236953 - head/sys/amd64/amd64 releng/7.4 releng/7.4/contrib/bind9/lib/dns releng/7.4/sys/amd64/amd64 releng/7.4/sys/conf releng/8.1 releng/8.1/contrib/bind9/lib/dns releng/8.1/sys/amd6...
Message-ID:  <201206121210.q5CCACYB052406@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Tue Jun 12 12:10:10 2012
New Revision: 236953
URL: http://svn.freebsd.org/changeset/base/236953

Log:
  Fix a problem where zero-length RDATA fields can cause named(8) to crash.
  [12:03]
  
  Correct a privilege escalation when returning from kernel if
  running FreeBSD/amd64 on non-AMD processors. [12:04]
  
  Fix reference count errors in IPv6 code. [EN-12:02]
  
  Security:	CVE-2012-1667
  Security:	FreeBSD-SA-12:03.bind
  Security:	CVE-2012-0217
  Security:	FreeBSD-SA-12:04.sysret
  Security:	FreeBSD-EN-12:02.ipv6refcount
  Approved by:	so (simon, bz)

Modified:
  releng/7.4/UPDATING
  releng/7.4/contrib/bind9/lib/dns/rdata.c
  releng/7.4/contrib/bind9/lib/dns/rdataslab.c
  releng/7.4/sys/amd64/amd64/trap.c
  releng/7.4/sys/conf/newvers.sh
  releng/8.1/UPDATING
  releng/8.1/contrib/bind9/lib/dns/rdata.c
  releng/8.1/contrib/bind9/lib/dns/rdataslab.c
  releng/8.1/sys/amd64/amd64/trap.c
  releng/8.1/sys/conf/newvers.sh
  releng/8.1/sys/netinet/tcp_input.c
  releng/8.1/sys/netinet6/in6.c
  releng/8.1/sys/netinet6/ip6_input.c
  releng/8.2/UPDATING
  releng/8.2/contrib/bind9/lib/dns/rdata.c
  releng/8.2/contrib/bind9/lib/dns/rdataslab.c
  releng/8.2/sys/amd64/amd64/trap.c
  releng/8.2/sys/conf/newvers.sh
  releng/8.2/sys/netinet/tcp_input.c
  releng/8.2/sys/netinet6/in6.c
  releng/8.2/sys/netinet6/ip6_input.c
  releng/8.3/UPDATING
  releng/8.3/contrib/bind9/lib/dns/rdata.c
  releng/8.3/contrib/bind9/lib/dns/rdataslab.c
  releng/8.3/sys/amd64/amd64/trap.c
  releng/8.3/sys/conf/newvers.sh
  releng/8.3/sys/netinet/tcp_input.c
  releng/8.3/sys/netinet6/in6.c
  releng/8.3/sys/netinet6/ip6_input.c
  releng/9.0/UPDATING
  releng/9.0/contrib/bind9/lib/dns/rdata.c
  releng/9.0/contrib/bind9/lib/dns/rdataslab.c
  releng/9.0/sys/amd64/amd64/trap.c
  releng/9.0/sys/conf/newvers.sh
  releng/9.0/sys/netinet/tcp_input.c
  releng/9.0/sys/netinet6/in6.c
  releng/9.0/sys/netinet6/ip6_input.c

Changes in other areas also in this revision:
Modified:
  head/sys/amd64/amd64/trap.c
  stable/7/contrib/bind9/lib/dns/rdata.c
  stable/7/contrib/bind9/lib/dns/rdataslab.c
  stable/7/sys/amd64/amd64/trap.c
  stable/8/sys/amd64/amd64/trap.c
  stable/9/sys/amd64/amd64/trap.c

Modified: releng/7.4/UPDATING
==============================================================================
--- releng/7.4/UPDATING	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/7.4/UPDATING	Tue Jun 12 12:10:10 2012	(r236953)
@@ -8,6 +8,14 @@ Items affecting the ports and packages s
 /usr/ports/UPDATING.  Please read that file before running
 portupgrade.
 
+20120612:	p9	FreeBSD-SA-12:03.bind
+			FreeBSD-SA-12:04.sysret
+	Fix a problem where zero-length RDATA fields can cause named to crash.
+	[12:03]
+
+	Correct a privilege escalation when returning from kernel if
+	running FreeBSD/amd64 on non-AMD processors. [12:04]
+
 20120530:	p8	FreeBSD-SA-12:01.openssl (revised),
 			FreeBSD-SA-12:02.crypt
 	Update the previous openssl fix. [12:01]

Modified: releng/7.4/contrib/bind9/lib/dns/rdata.c
==============================================================================
--- releng/7.4/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/7.4/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -334,8 +334,8 @@ dns_rdata_compare(const dns_rdata_t *rda
 
 	REQUIRE(rdata1 != NULL);
 	REQUIRE(rdata2 != NULL);
-	REQUIRE(rdata1->data != NULL);
-	REQUIRE(rdata2->data != NULL);
+	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
+	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 

Modified: releng/7.4/contrib/bind9/lib/dns/rdataslab.c
==============================================================================
--- releng/7.4/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/7.4/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -128,6 +128,11 @@ isc_result_t
 dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
 			   isc_region_t *region, unsigned int reservelen)
 {
+	/*
+	 * Use &removed as a sentinal pointer for duplicate
+	 * rdata as rdata.data == NULL is valid.
+	 */
+	static unsigned char removed;
 	struct xrdata  *x;
 	unsigned char  *rawbuf;
 #if DNS_RDATASET_FIXED
@@ -166,6 +171,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 		INSIST(result == ISC_R_SUCCESS);
 		dns_rdata_init(&x[i].rdata);
 		dns_rdataset_current(rdataset, &x[i].rdata);
+		INSIST(x[i].rdata.data != &removed);
 #if DNS_RDATASET_FIXED
 		x[i].order = i;
 #endif
@@ -198,8 +204,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 	 */
 	for (i = 1; i < nalloc; i++) {
 		if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
-			x[i-1].rdata.data = NULL;
-			x[i-1].rdata.length = 0;
+			x[i-1].rdata.data = &removed;
 #if DNS_RDATASET_FIXED
 			/*
 			 * Preserve the least order so A, B, A -> A, B
@@ -275,7 +280,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 #endif
 
 	for (i = 0; i < nalloc; i++) {
-		if (x[i].rdata.data == NULL)
+		if (x[i].rdata.data == &removed)
 			continue;
 #if DNS_RDATASET_FIXED
 		offsettable[x[i].order] = rawbuf - offsetbase;

Modified: releng/7.4/sys/amd64/amd64/trap.c
==============================================================================
--- releng/7.4/sys/amd64/amd64/trap.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/7.4/sys/amd64/amd64/trap.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -972,6 +972,23 @@ syscall(struct trapframe *frame)
 	/*
 	 * Traced syscall.
 	 */
+
+	/*
+	 * If the user-supplied value of %rip is not a canonical
+	 * address, then some CPUs will trigger a ring 0 #GP during
+	 * the sysret instruction.  However, the fault handler would
+	 * execute with the user's %gs and %rsp in ring 0 which would
+	 * not be safe.  Instead, preemptively kill the thread with a
+	 * SIGBUS.
+	 */
+	if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS) {
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)td->td_frame->tf_rip;
+		trapsignal(td, &ksi);
+	}
 	if (orig_tf_rflags & PSL_T) {
 		frame->tf_rflags &= ~PSL_T;
 		ksiginfo_init_trap(&ksi);

Modified: releng/7.4/sys/conf/newvers.sh
==============================================================================
--- releng/7.4/sys/conf/newvers.sh	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/7.4/sys/conf/newvers.sh	Tue Jun 12 12:10:10 2012	(r236953)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="7.4"
-BRANCH="RELEASE-p8"
+BRANCH="RELEASE-p9"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/8.1/UPDATING
==============================================================================
--- releng/8.1/UPDATING	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/UPDATING	Tue Jun 12 12:10:10 2012	(r236953)
@@ -15,6 +15,17 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.
 	debugging tools present in HEAD were left in place because
 	sun4v support still needs work to become production ready.
 
+20120612:	p11	FreeBSD-SA-12:03.bind
+			FreeBSD-SA-12:04.sysret
+			FreeBSD-EN-12:02.ipv6refcount
+	Fix a problem where zero-length RDATA fields can cause named to crash.
+	[12:03]
+
+	Correct a privilege escalation when returning from kernel if
+	running FreeBSD/amd64 on non-AMD processors. [12:04]
+
+	Fix reference count errors in IPv6 code. [EN-12:02]
+
 20120530:	p10	FreeBSD-SA-12:01.openssl (revised),
 			FreeBSD-SA-12:02.crypt
 	Update the previous openssl fix. [12:01]

Modified: releng/8.1/contrib/bind9/lib/dns/rdata.c
==============================================================================
--- releng/8.1/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -341,8 +341,8 @@ dns_rdata_compare(const dns_rdata_t *rda
 
 	REQUIRE(rdata1 != NULL);
 	REQUIRE(rdata2 != NULL);
-	REQUIRE(rdata1->data != NULL);
-	REQUIRE(rdata2->data != NULL);
+	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
+	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 

Modified: releng/8.1/contrib/bind9/lib/dns/rdataslab.c
==============================================================================
--- releng/8.1/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -125,6 +125,11 @@ isc_result_t
 dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
 			   isc_region_t *region, unsigned int reservelen)
 {
+	/*
+	 * Use &removed as a sentinal pointer for duplicate
+	 * rdata as rdata.data == NULL is valid.
+	 */
+	static unsigned char removed;
 	struct xrdata  *x;
 	unsigned char  *rawbuf;
 #if DNS_RDATASET_FIXED
@@ -164,6 +169,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 		INSIST(result == ISC_R_SUCCESS);
 		dns_rdata_init(&x[i].rdata);
 		dns_rdataset_current(rdataset, &x[i].rdata);
+		INSIST(x[i].rdata.data != &removed);
 #if DNS_RDATASET_FIXED
 		x[i].order = i;
 #endif
@@ -196,8 +202,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 	 */
 	for (i = 1; i < nalloc; i++) {
 		if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
-			x[i-1].rdata.data = NULL;
-			x[i-1].rdata.length = 0;
+			x[i-1].rdata.data = &removed;
 #if DNS_RDATASET_FIXED
 			/*
 			 * Preserve the least order so A, B, A -> A, B
@@ -284,7 +289,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 #endif
 
 	for (i = 0; i < nalloc; i++) {
-		if (x[i].rdata.data == NULL)
+		if (x[i].rdata.data == &removed)
 			continue;
 #if DNS_RDATASET_FIXED
 		offsettable[x[i].order] = rawbuf - offsetbase;

Modified: releng/8.1/sys/amd64/amd64/trap.c
==============================================================================
--- releng/8.1/sys/amd64/amd64/trap.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/sys/amd64/amd64/trap.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -972,6 +972,23 @@ syscall(struct trapframe *frame)
 		ksi.ksi_code = TRAP_TRACE;
 		ksi.ksi_addr = (void *)frame->tf_rip;
 		trapsignal(td, &ksi);
+
+	/*
+	 * If the user-supplied value of %rip is not a canonical
+	 * address, then some CPUs will trigger a ring 0 #GP during
+	 * the sysret instruction.  However, the fault handler would
+	 * execute with the user's %gs and %rsp in ring 0 which would
+	 * not be safe.  Instead, preemptively kill the thread with a
+	 * SIGBUS.
+	 */
+	if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS) {
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)td->td_frame->tf_rip;
+		trapsignal(td, &ksi);
+	}
 	}
 
 	/*

Modified: releng/8.1/sys/conf/newvers.sh
==============================================================================
--- releng/8.1/sys/conf/newvers.sh	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/sys/conf/newvers.sh	Tue Jun 12 12:10:10 2012	(r236953)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="8.1"
-BRANCH="RELEASE-p10"
+BRANCH="RELEASE-p11"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/8.1/sys/netinet/tcp_input.c
==============================================================================
--- releng/8.1/sys/netinet/tcp_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/sys/netinet/tcp_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -293,6 +293,8 @@ tcp6_input(struct mbuf **mp, int *offp, 
 			    (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
 		return IPPROTO_DONE;
 	}
+	if (ia6)
+		ifa_free(&ia6->ia_ifa);
 
 	tcp_input(m, *offp);
 	return IPPROTO_DONE;
@@ -941,7 +943,8 @@ relocked:
 				rstreason = BANDLIM_RST_OPENPORT;
 				goto dropwithreset;
 			}
-			ifa_free(&ia6->ia_ifa);
+			if (ia6)
+				ifa_free(&ia6->ia_ifa);
 		}
 #endif
 		/*

Modified: releng/8.1/sys/netinet6/in6.c
==============================================================================
--- releng/8.1/sys/netinet6/in6.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/sys/netinet6/in6.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -1370,6 +1370,8 @@ in6_purgeaddr(struct ifaddr *ifa)
 	}
 
 cleanup:
+	if (ifa0 != NULL)
+		ifa_free(ifa0);
 
 	plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
 	if ((ia->ia_flags & IFA_ROUTE) && plen == 128) {
@@ -1394,8 +1396,6 @@ cleanup:
 			return;
 		ia->ia_flags &= ~IFA_ROUTE;
 	}
-	if (ifa0 != NULL)
-		ifa_free(ifa0);
 
 	in6_unlink_ifa(ia, ifp);
 }
@@ -1549,14 +1549,19 @@ in6_lifaddr_ioctl(struct socket *so, u_l
 			hostid = IFA_IN6(ifa);
 
 			/* prefixlen must be <= 64. */
-			if (64 < iflr->prefixlen)
+			if (64 < iflr->prefixlen) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
+			}
 			prefixlen = iflr->prefixlen;
 
 			/* hostid part must be zero. */
 			sin6 = (struct sockaddr_in6 *)&iflr->addr;
 			if (sin6->sin6_addr.s6_addr32[2] != 0 ||
 			    sin6->sin6_addr.s6_addr32[3] != 0) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
 			}
 		} else
@@ -2144,14 +2149,20 @@ in6_ifawithifp(struct ifnet *ifp, struct
 		IN6_IFADDR_RUNLOCK();
 		return (struct in6_ifaddr *)ifa;
 	}
-	IN6_IFADDR_RUNLOCK();
 
 	/* use the last-resort values, that are, deprecated addresses */
-	if (dep[0])
+	if (dep[0]) {
+		ifa_ref((struct ifaddr *)dep[0]);
+		IN6_IFADDR_RUNLOCK();
 		return dep[0];
-	if (dep[1])
+	}
+	if (dep[1]) {
+		ifa_ref((struct ifaddr *)dep[1]);
+		IN6_IFADDR_RUNLOCK();
 		return dep[1];
+	}
 
+	IN6_IFADDR_RUNLOCK();
 	return NULL;
 }
 

Modified: releng/8.1/sys/netinet6/ip6_input.c
==============================================================================
--- releng/8.1/sys/netinet6/ip6_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.1/sys/netinet6/ip6_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -632,19 +632,23 @@ passin:
 	 * as our interface address (e.g. multicast addresses, addresses
 	 * within FAITH prefixes and such).
 	 */
-	if (deliverifp && !ip6_getdstifaddr(m)) {
+	if (deliverifp) {
 		struct in6_ifaddr *ia6;
 
-		ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
-		if (ia6) {
-			if (!ip6_setdstifaddr(m, ia6)) {
-				/*
-				 * XXX maybe we should drop the packet here,
-				 * as we could not provide enough information
-				 * to the upper layers.
-				 */
-			}
+ 		if ((ia6 = ip6_getdstifaddr(m)) != NULL) {
 			ifa_free(&ia6->ia_ifa);
+		} else {
+			ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
+			if (ia6) {
+				if (!ip6_setdstifaddr(m, ia6)) {
+					/*
+					 * XXX maybe we should drop the packet here,
+					 * as we could not provide enough information
+					 * to the upper layers.
+					 */
+				}
+				ifa_free(&ia6->ia_ifa);
+			}
 		}
 	}
 

Modified: releng/8.2/UPDATING
==============================================================================
--- releng/8.2/UPDATING	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/UPDATING	Tue Jun 12 12:10:10 2012	(r236953)
@@ -15,6 +15,17 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.
 	debugging tools present in HEAD were left in place because
 	sun4v support still needs work to become production ready.
 
+20120612:	p9	FreeBSD-SA-12:03.bind
+			FreeBSD-SA-12:04.sysret
+			FreeBSD-EN-12:02.ipv6refcount
+	Fix a problem where zero-length RDATA fields can cause named to crash.
+	[12:03]
+
+	Correct a privilege escalation when returning from kernel if
+	running FreeBSD/amd64 on non-AMD processors. [12:04]
+
+	Fix reference count errors in IPv6 code. [EN-12:02]
+
 20120530:	p8	FreeBSD-SA-12:01.openssl (revised),
 			FreeBSD-SA-12:02.crypt
 	Update the previous openssl fix. [12:01]

Modified: releng/8.2/contrib/bind9/lib/dns/rdata.c
==============================================================================
--- releng/8.2/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -341,8 +341,8 @@ dns_rdata_compare(const dns_rdata_t *rda
 
 	REQUIRE(rdata1 != NULL);
 	REQUIRE(rdata2 != NULL);
-	REQUIRE(rdata1->data != NULL);
-	REQUIRE(rdata2->data != NULL);
+	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
+	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 

Modified: releng/8.2/contrib/bind9/lib/dns/rdataslab.c
==============================================================================
--- releng/8.2/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -125,6 +125,11 @@ isc_result_t
 dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
 			   isc_region_t *region, unsigned int reservelen)
 {
+	/*
+	 * Use &removed as a sentinal pointer for duplicate
+	 * rdata as rdata.data == NULL is valid.
+	 */
+	static unsigned char removed;
 	struct xrdata  *x;
 	unsigned char  *rawbuf;
 #if DNS_RDATASET_FIXED
@@ -164,6 +169,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 		INSIST(result == ISC_R_SUCCESS);
 		dns_rdata_init(&x[i].rdata);
 		dns_rdataset_current(rdataset, &x[i].rdata);
+		INSIST(x[i].rdata.data != &removed);
 #if DNS_RDATASET_FIXED
 		x[i].order = i;
 #endif
@@ -196,8 +202,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 	 */
 	for (i = 1; i < nalloc; i++) {
 		if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
-			x[i-1].rdata.data = NULL;
-			x[i-1].rdata.length = 0;
+			x[i-1].rdata.data = &removed;
 #if DNS_RDATASET_FIXED
 			/*
 			 * Preserve the least order so A, B, A -> A, B
@@ -284,7 +289,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 #endif
 
 	for (i = 0; i < nalloc; i++) {
-		if (x[i].rdata.data == NULL)
+		if (x[i].rdata.data == &removed)
 			continue;
 #if DNS_RDATASET_FIXED
 		offsettable[x[i].order] = rawbuf - offsetbase;

Modified: releng/8.2/sys/amd64/amd64/trap.c
==============================================================================
--- releng/8.2/sys/amd64/amd64/trap.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/sys/amd64/amd64/trap.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -907,4 +907,21 @@ syscall(struct trapframe *frame)
 	     syscallname(td->td_proc, sa.code)));
 
 	syscallret(td, error, &sa);
+
+	/*
+	 * If the user-supplied value of %rip is not a canonical
+	 * address, then some CPUs will trigger a ring 0 #GP during
+	 * the sysret instruction.  However, the fault handler would
+	 * execute with the user's %gs and %rsp in ring 0 which would
+	 * not be safe.  Instead, preemptively kill the thread with a
+	 * SIGBUS.
+	 */
+	if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS) {
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)td->td_frame->tf_rip;
+		trapsignal(td, &ksi);
+	}
 }

Modified: releng/8.2/sys/conf/newvers.sh
==============================================================================
--- releng/8.2/sys/conf/newvers.sh	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/sys/conf/newvers.sh	Tue Jun 12 12:10:10 2012	(r236953)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="8.2"
-BRANCH="RELEASE-p8"
+BRANCH="RELEASE-p9"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/8.2/sys/netinet/tcp_input.c
==============================================================================
--- releng/8.2/sys/netinet/tcp_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/sys/netinet/tcp_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -293,6 +293,8 @@ tcp6_input(struct mbuf **mp, int *offp, 
 			    (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
 		return IPPROTO_DONE;
 	}
+	if (ia6)
+		ifa_free(&ia6->ia_ifa);
 
 	tcp_input(m, *offp);
 	return IPPROTO_DONE;
@@ -941,7 +943,8 @@ relocked:
 				rstreason = BANDLIM_RST_OPENPORT;
 				goto dropwithreset;
 			}
-			ifa_free(&ia6->ia_ifa);
+			if (ia6)
+				ifa_free(&ia6->ia_ifa);
 		}
 #endif
 		/*

Modified: releng/8.2/sys/netinet6/in6.c
==============================================================================
--- releng/8.2/sys/netinet6/in6.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/sys/netinet6/in6.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -1370,6 +1370,8 @@ in6_purgeaddr(struct ifaddr *ifa)
 	}
 
 cleanup:
+	if (ifa0 != NULL)
+		ifa_free(ifa0);
 
 	plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
 	if ((ia->ia_flags & IFA_ROUTE) && plen == 128) {
@@ -1394,8 +1396,6 @@ cleanup:
 			return;
 		ia->ia_flags &= ~IFA_ROUTE;
 	}
-	if (ifa0 != NULL)
-		ifa_free(ifa0);
 
 	in6_unlink_ifa(ia, ifp);
 }
@@ -1549,14 +1549,19 @@ in6_lifaddr_ioctl(struct socket *so, u_l
 			hostid = IFA_IN6(ifa);
 
 			/* prefixlen must be <= 64. */
-			if (64 < iflr->prefixlen)
+			if (64 < iflr->prefixlen) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
+			}
 			prefixlen = iflr->prefixlen;
 
 			/* hostid part must be zero. */
 			sin6 = (struct sockaddr_in6 *)&iflr->addr;
 			if (sin6->sin6_addr.s6_addr32[2] != 0 ||
 			    sin6->sin6_addr.s6_addr32[3] != 0) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
 			}
 		} else
@@ -2144,14 +2149,20 @@ in6_ifawithifp(struct ifnet *ifp, struct
 		IN6_IFADDR_RUNLOCK();
 		return (struct in6_ifaddr *)ifa;
 	}
-	IN6_IFADDR_RUNLOCK();
 
 	/* use the last-resort values, that are, deprecated addresses */
-	if (dep[0])
+	if (dep[0]) {
+		ifa_ref((struct ifaddr *)dep[0]);
+		IN6_IFADDR_RUNLOCK();
 		return dep[0];
-	if (dep[1])
+	}
+	if (dep[1]) {
+		ifa_ref((struct ifaddr *)dep[1]);
+		IN6_IFADDR_RUNLOCK();
 		return dep[1];
+	}
 
+	IN6_IFADDR_RUNLOCK();
 	return NULL;
 }
 

Modified: releng/8.2/sys/netinet6/ip6_input.c
==============================================================================
--- releng/8.2/sys/netinet6/ip6_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.2/sys/netinet6/ip6_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -734,19 +734,23 @@ passin:
 	 * as our interface address (e.g. multicast addresses, addresses
 	 * within FAITH prefixes and such).
 	 */
-	if (deliverifp && !ip6_getdstifaddr(m)) {
+	if (deliverifp) {
 		struct in6_ifaddr *ia6;
 
-		ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
-		if (ia6) {
-			if (!ip6_setdstifaddr(m, ia6)) {
-				/*
-				 * XXX maybe we should drop the packet here,
-				 * as we could not provide enough information
-				 * to the upper layers.
-				 */
-			}
+ 		if ((ia6 = ip6_getdstifaddr(m)) != NULL) {
 			ifa_free(&ia6->ia_ifa);
+		} else {
+			ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
+			if (ia6) {
+				if (!ip6_setdstifaddr(m, ia6)) {
+					/*
+					 * XXX maybe we should drop the packet here,
+					 * as we could not provide enough information
+					 * to the upper layers.
+					 */
+				}
+				ifa_free(&ia6->ia_ifa);
+			}
 		}
 	}
 

Modified: releng/8.3/UPDATING
==============================================================================
--- releng/8.3/UPDATING	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/UPDATING	Tue Jun 12 12:10:10 2012	(r236953)
@@ -15,6 +15,17 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.
 	debugging tools present in HEAD were left in place because
 	sun4v support still needs work to become production ready.
 
+20120612:	p3	FreeBSD-SA-12:03.bind
+			FreeBSD-SA-12:04.sysret
+			FreeBSD-EN-12:02.ipv6refcount
+	Fix a problem where zero-length RDATA fields can cause named to crash.
+	[12:03]
+
+	Correct a privilege escalation when returning from kernel if
+	running FreeBSD/amd64 on non-AMD processors. [12:04]
+
+	Fix reference count errors in IPv6 code. [EN-12:02]
+
 20120530:	p2	FreeBSD-SA-12:01.openssl (revised),
 			FreeBSD-SA-12:02.crypt
 	Update the previous openssl fix. [12:01]

Modified: releng/8.3/contrib/bind9/lib/dns/rdata.c
==============================================================================
--- releng/8.3/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -341,8 +341,8 @@ dns_rdata_compare(const dns_rdata_t *rda
 
 	REQUIRE(rdata1 != NULL);
 	REQUIRE(rdata2 != NULL);
-	REQUIRE(rdata1->data != NULL);
-	REQUIRE(rdata2->data != NULL);
+	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
+	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 

Modified: releng/8.3/contrib/bind9/lib/dns/rdataslab.c
==============================================================================
--- releng/8.3/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -125,6 +125,11 @@ isc_result_t
 dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
 			   isc_region_t *region, unsigned int reservelen)
 {
+	/*
+	 * Use &removed as a sentinal pointer for duplicate
+	 * rdata as rdata.data == NULL is valid.
+	 */
+	static unsigned char removed;
 	struct xrdata  *x;
 	unsigned char  *rawbuf;
 #if DNS_RDATASET_FIXED
@@ -164,6 +169,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 		INSIST(result == ISC_R_SUCCESS);
 		dns_rdata_init(&x[i].rdata);
 		dns_rdataset_current(rdataset, &x[i].rdata);
+		INSIST(x[i].rdata.data != &removed);
 #if DNS_RDATASET_FIXED
 		x[i].order = i;
 #endif
@@ -196,8 +202,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 	 */
 	for (i = 1; i < nalloc; i++) {
 		if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
-			x[i-1].rdata.data = NULL;
-			x[i-1].rdata.length = 0;
+			x[i-1].rdata.data = &removed;
 #if DNS_RDATASET_FIXED
 			/*
 			 * Preserve the least order so A, B, A -> A, B
@@ -284,7 +289,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 #endif
 
 	for (i = 0; i < nalloc; i++) {
-		if (x[i].rdata.data == NULL)
+		if (x[i].rdata.data == &removed)
 			continue;
 #if DNS_RDATASET_FIXED
 		offsettable[x[i].order] = rawbuf - offsetbase;

Modified: releng/8.3/sys/amd64/amd64/trap.c
==============================================================================
--- releng/8.3/sys/amd64/amd64/trap.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/sys/amd64/amd64/trap.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -945,4 +945,21 @@ amd64_syscall(struct thread *td, int tra
 	     syscallname(td->td_proc, sa.code)));
 
 	syscallret(td, error, &sa);
+
+	/*
+	 * If the user-supplied value of %rip is not a canonical
+	 * address, then some CPUs will trigger a ring 0 #GP during
+	 * the sysret instruction.  However, the fault handler would
+	 * execute with the user's %gs and %rsp in ring 0 which would
+	 * not be safe.  Instead, preemptively kill the thread with a
+	 * SIGBUS.
+	 */
+	if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS) {
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)td->td_frame->tf_rip;
+		trapsignal(td, &ksi);
+	}
 }

Modified: releng/8.3/sys/conf/newvers.sh
==============================================================================
--- releng/8.3/sys/conf/newvers.sh	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/sys/conf/newvers.sh	Tue Jun 12 12:10:10 2012	(r236953)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="8.3"
-BRANCH="RELEASE-p2"
+BRANCH="RELEASE-p3"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/8.3/sys/netinet/tcp_input.c
==============================================================================
--- releng/8.3/sys/netinet/tcp_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/sys/netinet/tcp_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -538,6 +538,8 @@ tcp6_input(struct mbuf **mp, int *offp, 
 			    (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
 		return IPPROTO_DONE;
 	}
+	if (ia6)
+		ifa_free(&ia6->ia_ifa);
 
 	tcp_input(m, *offp);
 	return IPPROTO_DONE;
@@ -1206,7 +1208,8 @@ relocked:
 				rstreason = BANDLIM_RST_OPENPORT;
 				goto dropwithreset;
 			}
-			ifa_free(&ia6->ia_ifa);
+			if (ia6)
+				ifa_free(&ia6->ia_ifa);
 		}
 #endif
 		/*

Modified: releng/8.3/sys/netinet6/in6.c
==============================================================================
--- releng/8.3/sys/netinet6/in6.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/sys/netinet6/in6.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -1548,14 +1548,19 @@ in6_lifaddr_ioctl(struct socket *so, u_l
 			hostid = IFA_IN6(ifa);
 
 			/* prefixlen must be <= 64. */
-			if (64 < iflr->prefixlen)
+			if (64 < iflr->prefixlen) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
+			}
 			prefixlen = iflr->prefixlen;
 
 			/* hostid part must be zero. */
 			sin6 = (struct sockaddr_in6 *)&iflr->addr;
 			if (sin6->sin6_addr.s6_addr32[2] != 0 ||
 			    sin6->sin6_addr.s6_addr32[3] != 0) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
 			}
 		} else
@@ -2148,14 +2153,20 @@ in6_ifawithifp(struct ifnet *ifp, struct
 		IF_ADDR_UNLOCK(ifp);
 		return (struct in6_ifaddr *)ifa;
 	}
-	IF_ADDR_UNLOCK(ifp);
 
 	/* use the last-resort values, that are, deprecated addresses */
-	if (dep[0])
+	if (dep[0]) {
+		ifa_ref((struct ifaddr *)dep[0]);
+		IF_ADDR_UNLOCK(ifp);
 		return dep[0];
-	if (dep[1])
+	}
+	if (dep[1]) {
+		ifa_ref((struct ifaddr *)dep[1]);
+		IF_ADDR_UNLOCK(ifp);
 		return dep[1];
+	}
 
+	IF_ADDR_UNLOCK(ifp);
 	return NULL;
 }
 

Modified: releng/8.3/sys/netinet6/ip6_input.c
==============================================================================
--- releng/8.3/sys/netinet6/ip6_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/8.3/sys/netinet6/ip6_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -734,19 +734,23 @@ passin:
 	 * as our interface address (e.g. multicast addresses, addresses
 	 * within FAITH prefixes and such).
 	 */
-	if (deliverifp && !ip6_getdstifaddr(m)) {
+	if (deliverifp) {
 		struct in6_ifaddr *ia6;
 
-		ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
-		if (ia6) {
-			if (!ip6_setdstifaddr(m, ia6)) {
-				/*
-				 * XXX maybe we should drop the packet here,
-				 * as we could not provide enough information
-				 * to the upper layers.
-				 */
-			}
+ 		if ((ia6 = ip6_getdstifaddr(m)) != NULL) {
 			ifa_free(&ia6->ia_ifa);
+		} else {
+			ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
+			if (ia6) {
+				if (!ip6_setdstifaddr(m, ia6)) {
+					/*
+					 * XXX maybe we should drop the packet here,
+					 * as we could not provide enough information
+					 * to the upper layers.
+					 */
+				}
+				ifa_free(&ia6->ia_ifa);
+			}
 		}
 	}
 

Modified: releng/9.0/UPDATING
==============================================================================
--- releng/9.0/UPDATING	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/UPDATING	Tue Jun 12 12:10:10 2012	(r236953)
@@ -9,6 +9,17 @@ handbook.
 Items affecting the ports and packages system can be found in
 /usr/ports/UPDATING.  Please read that file before running portupgrade.
 
+20120612:	p3	FreeBSD-SA-12:03.bind
+			FreeBSD-SA-12:04.sysret
+			FreeBSD-EN-12:02.ipv6refcount
+	Fix a problem where zero-length RDATA fields can cause named to crash.
+	[12:03]
+
+	Correct a privilege escalation when returning from kernel if
+	running FreeBSD/amd64 on non-AMD processors. [12:04]
+
+	Fix reference count errors in IPv6 code. [EN-12:02]
+
 20120530:	p2	FreeBSD-SA-12:01.openssl (revised),
 			FreeBSD-SA-12:02.crypt
 	Update the previous openssl fix. [12:01]

Modified: releng/9.0/contrib/bind9/lib/dns/rdata.c
==============================================================================
--- releng/9.0/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/contrib/bind9/lib/dns/rdata.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -325,8 +325,8 @@ dns_rdata_compare(const dns_rdata_t *rda
 
 	REQUIRE(rdata1 != NULL);
 	REQUIRE(rdata2 != NULL);
-	REQUIRE(rdata1->data != NULL);
-	REQUIRE(rdata2->data != NULL);
+	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
+	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 
@@ -356,8 +356,8 @@ dns_rdata_casecompare(const dns_rdata_t 
 
 	REQUIRE(rdata1 != NULL);
 	REQUIRE(rdata2 != NULL);
-	REQUIRE(rdata1->data != NULL);
-	REQUIRE(rdata2->data != NULL);
+	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
+	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 

Modified: releng/9.0/contrib/bind9/lib/dns/rdataslab.c
==============================================================================
--- releng/9.0/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/contrib/bind9/lib/dns/rdataslab.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -125,6 +125,11 @@ isc_result_t
 dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
 			   isc_region_t *region, unsigned int reservelen)
 {
+	/*
+	 * Use &removed as a sentinal pointer for duplicate
+	 * rdata as rdata.data == NULL is valid.
+	 */
+	static unsigned char removed;
 	struct xrdata  *x;
 	unsigned char  *rawbuf;
 #if DNS_RDATASET_FIXED
@@ -168,6 +173,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 		INSIST(result == ISC_R_SUCCESS);
 		dns_rdata_init(&x[i].rdata);
 		dns_rdataset_current(rdataset, &x[i].rdata);
+		INSIST(x[i].rdata.data != &removed);
 #if DNS_RDATASET_FIXED
 		x[i].order = i;
 #endif
@@ -200,8 +206,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 	 */
 	for (i = 1; i < nalloc; i++) {
 		if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
-			x[i-1].rdata.data = NULL;
-			x[i-1].rdata.length = 0;
+			x[i-1].rdata.data = &removed;
 #if DNS_RDATASET_FIXED
 			/*
 			 * Preserve the least order so A, B, A -> A, B
@@ -291,7 +296,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 #endif
 
 	for (i = 0; i < nalloc; i++) {
-		if (x[i].rdata.data == NULL)
+		if (x[i].rdata.data == &removed)
 			continue;
 #if DNS_RDATASET_FIXED
 		offsettable[x[i].order] = rawbuf - offsetbase;

Modified: releng/9.0/sys/amd64/amd64/trap.c
==============================================================================
--- releng/9.0/sys/amd64/amd64/trap.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/sys/amd64/amd64/trap.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -939,4 +939,21 @@ amd64_syscall(struct thread *td, int tra
 	     syscallname(td->td_proc, sa.code)));
 
 	syscallret(td, error, &sa);
+
+	/*
+	 * If the user-supplied value of %rip is not a canonical
+	 * address, then some CPUs will trigger a ring 0 #GP during
+	 * the sysret instruction.  However, the fault handler would
+	 * execute with the user's %gs and %rsp in ring 0 which would
+	 * not be safe.  Instead, preemptively kill the thread with a
+	 * SIGBUS.
+	 */
+	if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS) {
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)td->td_frame->tf_rip;
+		trapsignal(td, &ksi);
+	}
 }

Modified: releng/9.0/sys/conf/newvers.sh
==============================================================================
--- releng/9.0/sys/conf/newvers.sh	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/sys/conf/newvers.sh	Tue Jun 12 12:10:10 2012	(r236953)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="9.0"
-BRANCH="RELEASE-p2"
+BRANCH="RELEASE-p3"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/9.0/sys/netinet/tcp_input.c
==============================================================================
--- releng/9.0/sys/netinet/tcp_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/sys/netinet/tcp_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -543,6 +543,8 @@ tcp6_input(struct mbuf **mp, int *offp, 
 			    (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
 		return IPPROTO_DONE;
 	}
+	if (ia6)
+		ifa_free(&ia6->ia_ifa);
 
 	tcp_input(m, *offp);
 	return IPPROTO_DONE;
@@ -1253,7 +1255,8 @@ relocked:
 				rstreason = BANDLIM_RST_OPENPORT;
 				goto dropwithreset;
 			}
-			ifa_free(&ia6->ia_ifa);
+			if (ia6)
+				ifa_free(&ia6->ia_ifa);
 		}
 #endif /* INET6 */
 		/*

Modified: releng/9.0/sys/netinet6/in6.c
==============================================================================
--- releng/9.0/sys/netinet6/in6.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/sys/netinet6/in6.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -1453,6 +1453,8 @@ in6_purgeaddr(struct ifaddr *ifa)
 	}
 
 cleanup:
+	if (ifa0 != NULL)
+		ifa_free(ifa0);
 
 	plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
 	if ((ia->ia_flags & IFA_ROUTE) && plen == 128) {
@@ -1477,8 +1479,6 @@ cleanup:
 			return;
 		ia->ia_flags &= ~IFA_ROUTE;
 	}
-	if (ifa0 != NULL)
-		ifa_free(ifa0);
 
 	in6_unlink_ifa(ia, ifp);
 }
@@ -1632,14 +1632,19 @@ in6_lifaddr_ioctl(struct socket *so, u_l
 			hostid = IFA_IN6(ifa);
 
 			/* prefixlen must be <= 64. */
-			if (64 < iflr->prefixlen)
+			if (64 < iflr->prefixlen) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
+			}
 			prefixlen = iflr->prefixlen;
 
 			/* hostid part must be zero. */
 			sin6 = (struct sockaddr_in6 *)&iflr->addr;
 			if (sin6->sin6_addr.s6_addr32[2] != 0 ||
 			    sin6->sin6_addr.s6_addr32[3] != 0) {
+				if (ifa != NULL)
+					ifa_free(ifa);
 				return EINVAL;
 			}
 		} else
@@ -2230,14 +2235,20 @@ in6_ifawithifp(struct ifnet *ifp, struct
 		IN6_IFADDR_RUNLOCK();
 		return (struct in6_ifaddr *)ifa;
 	}
-	IN6_IFADDR_RUNLOCK();
 
 	/* use the last-resort values, that are, deprecated addresses */
-	if (dep[0])
+	if (dep[0]) {
+		ifa_ref((struct ifaddr *)dep[0]);
+		IN6_IFADDR_RUNLOCK();
 		return dep[0];
-	if (dep[1])
+	}
+	if (dep[1]) {
+		ifa_ref((struct ifaddr *)dep[1]);
+		IN6_IFADDR_RUNLOCK();
 		return dep[1];
+	}
 
+	IN6_IFADDR_RUNLOCK();
 	return NULL;
 }
 

Modified: releng/9.0/sys/netinet6/ip6_input.c
==============================================================================
--- releng/9.0/sys/netinet6/ip6_input.c	Tue Jun 12 11:08:51 2012	(r236952)
+++ releng/9.0/sys/netinet6/ip6_input.c	Tue Jun 12 12:10:10 2012	(r236953)
@@ -797,19 +797,23 @@ passin:
 	 * as our interface address (e.g. multicast addresses, addresses
 	 * within FAITH prefixes and such).
 	 */
-	if (deliverifp && !ip6_getdstifaddr(m)) {
+	if (deliverifp) {
 		struct in6_ifaddr *ia6;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206121210.q5CCACYB052406>