svn commit: r229414 - head/sys/netinet6
John Baldwin
jhb at FreeBSD.org
Tue Jan 3 19:44:37 UTC 2012
Author: jhb
Date: Tue Jan 3 19:44:36 2012
New Revision: 229414
URL: http://svn.freebsd.org/changeset/base/229414
Log:
Grab a reference on the matching interface address (ifa) in the handling
of the SIOC[DG]LIFADDR icotls before dropping the IF_ADDR_LOCK() and
release the reference after using it. This prevents the address from
being potentially freed out from under the ioctl handler.
Reviewed by: bz
MFC after: 1 week
Modified:
head/sys/netinet6/in6.c
Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c Tue Jan 3 19:41:36 2012 (r229413)
+++ head/sys/netinet6/in6.c Tue Jan 3 19:44:36 2012 (r229414)
@@ -1767,6 +1767,8 @@ in6_lifaddr_ioctl(struct socket *so, u_l
if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
break;
}
+ if (ifa != NULL)
+ ifa_ref(ifa);
IF_ADDR_UNLOCK(ifp);
if (!ifa)
return EADDRNOTAVAIL;
@@ -1779,16 +1781,20 @@ in6_lifaddr_ioctl(struct socket *so, u_l
bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
error = sa6_recoverscope(
(struct sockaddr_in6 *)&iflr->addr);
- if (error != 0)
+ if (error != 0) {
+ ifa_free(ifa);
return (error);
+ }
if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
ia->ia_dstaddr.sin6_len);
error = sa6_recoverscope(
(struct sockaddr_in6 *)&iflr->dstaddr);
- if (error != 0)
+ if (error != 0) {
+ ifa_free(ifa);
return (error);
+ }
} else
bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
@@ -1796,6 +1802,7 @@ in6_lifaddr_ioctl(struct socket *so, u_l
in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
iflr->flags = ia->ia6_flags; /* XXX */
+ ifa_free(ifa);
return 0;
} else {
@@ -1819,6 +1826,7 @@ in6_lifaddr_ioctl(struct socket *so, u_l
ia->ia_prefixmask.sin6_len);
ifra.ifra_flags = ia->ia6_flags;
+ ifa_free(ifa);
return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
ifp, td);
}
More information about the svn-src-head
mailing list