diff options
author | dg <dg@FreeBSD.org> | 1996-04-07 06:59:52 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1996-04-07 06:59:52 +0000 |
commit | d12b1628eddfaa5a8119eb30774a6543be9b3a77 (patch) | |
tree | d1e09cfaab4a825b94bf2f7f58eaf4b79b124448 /sys | |
parent | 61af07d0231e53139c2d8c49081a0f43da46af74 (diff) | |
download | FreeBSD-src-d12b1628eddfaa5a8119eb30774a6543be9b3a77.zip FreeBSD-src-d12b1628eddfaa5a8119eb30774a6543be9b3a77.tar.gz |
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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/in.c | 19 |
1 files changed, 17 insertions, 2 deletions
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 <sys/param.h> @@ -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: |