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
This commit is contained in:
parent
35a4bf1ce0
commit
fe0fc7efe3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149943
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user