From d12b1628eddfaa5a8119eb30774a6543be9b3a77 Mon Sep 17 00:00:00 2001 From: dg Date: Sun, 7 Apr 1996 06:59:52 +0000 Subject: Added proper splnet protection while modifying the interface address list. This fixes a panic that occurs when ifconfig ioctl(s) were interrupted by IP traffic at the wrong time - resulting in a NULL pointer dereference. This was originally noticed on a FreeBSD 1.0 system, but the problem still exists in current sources. --- sys/netinet/in.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'sys/netinet/in.c') diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 7455b6a..dd1db1f 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)in.c 8.4 (Berkeley) 1/9/95 - * $Id: in.c,v 1.22 1996/03/11 15:13:12 davidg Exp $ + * $Id: in.c,v 1.23 1996/03/15 17:08:07 fenner Exp $ */ #include @@ -160,7 +160,7 @@ in_control(so, cmd, data, ifp) struct in_ifaddr *oia; struct in_aliasreq *ifra = (struct in_aliasreq *)data; struct sockaddr_in oldaddr; - int error, hostIsNew, maskIsNew; + int error, hostIsNew, maskIsNew, s; u_long i; struct multi_kludge *mk; @@ -220,6 +220,12 @@ in_control(so, cmd, data, ifp) return (ENOBUFS); bzero((caddr_t)oia, sizeof *oia); ia = in_ifaddr; + /* + * Protect from ipintr() traversing address list + * while we're modifying it. + */ + s = splnet(); + if (ia) { for ( ; ia->ia_next; ia = ia->ia_next) continue; @@ -247,6 +253,7 @@ in_control(so, cmd, data, ifp) ia->ia_ifp = ifp; if (!(ifp->if_flags & IFF_LOOPBACK)) in_interfaces++; + splx(s); } break; @@ -358,6 +365,12 @@ in_control(so, cmd, data, ifp) return ENOBUFS; in_ifscrub(ifp, ia); + /* + * Protect from ipintr() traversing address list + * while we're modifying it. + */ + s = splnet(); + if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) ifp->if_addrlist = ifa->ifa_next; else { @@ -384,6 +397,7 @@ in_control(so, cmd, data, ifp) if (!oia->ia_multiaddrs.lh_first) { IFAFREE(&oia->ia_ifa); FREE(mk, M_IPMADDR); + splx(s); break; } @@ -425,6 +439,7 @@ in_control(so, cmd, data, ifp) } IFAFREE((&oia->ia_ifa)); + splx(s); break; default: -- cgit v1.1