From 7bdd5fbb1cb592f83faf06d49d6403302c17f0dc Mon Sep 17 00:00:00 2001 From: csjp Date: Sat, 10 Sep 2005 15:12:24 +0000 Subject: Protect interface and address lists using the appropriate mutex. These locks were not aquired because the user buffers were not wired, thus it was possible that that SYSCTL_OUT could sleep, causing a number of different problems such as lock ordering issues and dead locks. -Wire user supplied buffer to ensure SYSCTL_OUT will not sleep. -Pickup ifnet locks to protect the list. -Where applicable pickup address locks. -Pickup radix node head locks. -Remove splnet stubs -Remove various comments about locking here, because they are no longer needed. It is the hope that these changes will make sysctl_rtsock MP safe. MFC after: 3 weeks --- sys/net/rtsock.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'sys/net/rtsock.c') diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index cf34315..cceeb19 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1089,7 +1089,7 @@ sysctl_iflist(int af, struct walkarg *w) int len, error = 0; bzero((caddr_t)&info, sizeof(info)); - /* IFNET_RLOCK(); */ /* could sleep XXX */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (w->w_arg && w->w_arg != ifp->if_index) continue; @@ -1136,7 +1136,7 @@ sysctl_iflist(int af, struct walkarg *w) info.rti_info[RTAX_BRD] = NULL; } done: - /* IFNET_RUNLOCK(); */ /* XXX */ + IFNET_RUNLOCK(); return (error); } @@ -1150,17 +1150,13 @@ sysctl_ifmalist(int af, struct walkarg *w) struct ifaddr *ifa; bzero((caddr_t)&info, sizeof(info)); - /* IFNET_RLOCK(); */ /* could sleep XXX */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (w->w_arg && w->w_arg != ifp->if_index) continue; ifa = ifaddr_byindex(ifp->if_index); info.rti_info[RTAX_IFP] = ifa ? ifa->ifa_addr : NULL; - - /* - * XXXRW: Can't acquire IF_ADDR_LOCK() due to call - * to SYSCTL_OUT(). - */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (af && af != ifma->ifma_addr->sa_family) continue; @@ -1180,13 +1176,16 @@ sysctl_ifmalist(int af, struct walkarg *w) ifmam->ifmam_flags = 0; ifmam->ifmam_addrs = info.rti_addrs; error = SYSCTL_OUT(w->w_req, w->w_tmem, len); - if (error) + if (error) { + IF_ADDR_UNLOCK(ifp); goto done; + } } } + IF_ADDR_UNLOCK(ifp); } done: - /* IFNET_RUNLOCK(); */ /* XXX */ + IFNET_RUNLOCK(); return (error); } @@ -1196,7 +1195,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) int *name = (int *)arg1; u_int namelen = arg2; struct radix_node_head *rnh; - int i, lim, s, error = EINVAL; + int i, lim, error = EINVAL; u_char af; struct walkarg w; @@ -1214,7 +1213,9 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) w.w_arg = name[2]; w.w_req = req; - s = splnet(); + error = sysctl_wire_old_buffer(req, 0); + if (error) + return (error); switch (w.w_op) { case NET_RT_DUMP: @@ -1226,10 +1227,10 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) i = lim = af; for (error = 0; error == 0 && i <= lim; i++) if ((rnh = rt_tables[i]) != NULL) { - /* RADIX_NODE_HEAD_LOCK(rnh); */ + RADIX_NODE_HEAD_LOCK(rnh); error = rnh->rnh_walktree(rnh, - sysctl_dumpentry, &w);/* could sleep XXX */ - /* RADIX_NODE_HEAD_UNLOCK(rnh); */ + sysctl_dumpentry, &w); + RADIX_NODE_HEAD_UNLOCK(rnh); } else if (af != 0) error = EAFNOSUPPORT; break; @@ -1242,7 +1243,6 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) error = sysctl_ifmalist(af, &w); break; } - splx(s); if (w.w_tmem) free(w.w_tmem, M_RTABLE); return (error); -- cgit v1.1