summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1996-04-07 06:59:52 +0000
committerdg <dg@FreeBSD.org>1996-04-07 06:59:52 +0000
commitd12b1628eddfaa5a8119eb30774a6543be9b3a77 (patch)
treed1e09cfaab4a825b94bf2f7f58eaf4b79b124448 /sys
parent61af07d0231e53139c2d8c49081a0f43da46af74 (diff)
downloadFreeBSD-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.c19
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:
OpenPOWER on IntegriCloud