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...
Bjoern A. Zeeb
bz at FreeBSD.org
Tue Jun 12 12:10:13 UTC 2012
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 ***
More information about the svn-src-all
mailing list