svn commit: r191285 - head/sys/netinet
Robert Watson
rwatson at FreeBSD.org
Sun Apr 19 22:16:20 UTC 2009
Author: rwatson
Date: Sun Apr 19 22:16:19 2009
New Revision: 191285
URL: http://svn.freebsd.org/changeset/base/191285
Log:
Protect against some writer-writer races in in_control() by acquiring
the interface address list lock around interface address list
modifications. More to do here.
MFC after: 2 weeks
Modified:
head/sys/netinet/in.c
Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c Sun Apr 19 22:05:39 2009 (r191284)
+++ head/sys/netinet/in.c Sun Apr 19 22:16:19 2009 (r191285)
@@ -330,14 +330,12 @@ in_control(struct socket *so, u_long cmd
* Protect from ipintr() traversing address list
* while we're modifying it.
*/
- s = splnet();
ifa = &ia->ia_ifa;
IFA_LOCK_INIT(ifa);
ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
ifa->ifa_refcnt = 1;
- TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
ia->ia_sockmask.sin_len = 8;
ia->ia_sockmask.sin_family = AF_INET;
@@ -347,6 +345,10 @@ in_control(struct socket *so, u_long cmd
}
ia->ia_ifp = ifp;
+ IF_ADDR_LOCK(ifp);
+ TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
+ IF_ADDR_UNLOCK(ifp);
+ s = splnet();
TAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link);
splx(s);
iaIsNew = 1;
@@ -512,8 +514,10 @@ in_control(struct socket *so, u_long cmd
* Protect from ipintr() traversing address list while we're modifying
* it.
*/
- s = splnet();
+ IF_ADDR_LOCK(ifp);
TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
+ IF_ADDR_UNLOCK(ifp);
+ s = splnet();
TAILQ_REMOVE(&V_in_ifaddrhead, ia, ia_link);
if (ia->ia_addr.sin_family == AF_INET) {
LIST_REMOVE(ia, ia_hash);
More information about the svn-src-all
mailing list