Acquire Giant conditionally in in_addmulti() and in_delmulti() based on
whether the interface being accessed is IFF_NEEDSGIANT or not. This avoids lock order reversals when calling into the interface ioctl handler, which could potentially lead to deadlock. The long term solution is to eliminate non-MPSAFE network drivers. Discussed with: jhb MFC after: 1 week
This commit is contained in:
parent
6fa40729c8
commit
1fa9efeffb
@ -961,6 +961,7 @@ in_addmulti(ap, ifp)
|
|||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
struct ifmultiaddr *ifma;
|
struct ifmultiaddr *ifma;
|
||||||
|
|
||||||
|
IFF_LOCKGIANT(ifp);
|
||||||
IN_MULTI_LOCK();
|
IN_MULTI_LOCK();
|
||||||
/*
|
/*
|
||||||
* Call generic routine to add membership or increment
|
* Call generic routine to add membership or increment
|
||||||
@ -974,6 +975,7 @@ in_addmulti(ap, ifp)
|
|||||||
error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
|
error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
|
||||||
if (error) {
|
if (error) {
|
||||||
IN_MULTI_UNLOCK();
|
IN_MULTI_UNLOCK();
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -983,6 +985,7 @@ in_addmulti(ap, ifp)
|
|||||||
*/
|
*/
|
||||||
if (ifma->ifma_protospec != NULL) {
|
if (ifma->ifma_protospec != NULL) {
|
||||||
IN_MULTI_UNLOCK();
|
IN_MULTI_UNLOCK();
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
return ifma->ifma_protospec;
|
return ifma->ifma_protospec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -990,6 +993,7 @@ in_addmulti(ap, ifp)
|
|||||||
M_NOWAIT | M_ZERO);
|
M_NOWAIT | M_ZERO);
|
||||||
if (inm == NULL) {
|
if (inm == NULL) {
|
||||||
IN_MULTI_UNLOCK();
|
IN_MULTI_UNLOCK();
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,6 +1008,7 @@ in_addmulti(ap, ifp)
|
|||||||
*/
|
*/
|
||||||
igmp_joingroup(inm);
|
igmp_joingroup(inm);
|
||||||
IN_MULTI_UNLOCK();
|
IN_MULTI_UNLOCK();
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
return (inm);
|
return (inm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,7 +1021,10 @@ in_delmulti(inm)
|
|||||||
{
|
{
|
||||||
struct ifmultiaddr *ifma;
|
struct ifmultiaddr *ifma;
|
||||||
struct in_multi my_inm;
|
struct in_multi my_inm;
|
||||||
|
struct ifnet *ifp;
|
||||||
|
|
||||||
|
ifp = inm->inm_ifp;
|
||||||
|
IFF_LOCKGIANT(ifp);
|
||||||
IN_MULTI_LOCK();
|
IN_MULTI_LOCK();
|
||||||
ifma = inm->inm_ifma;
|
ifma = inm->inm_ifma;
|
||||||
my_inm.inm_ifp = NULL ; /* don't send the leave msg */
|
my_inm.inm_ifp = NULL ; /* don't send the leave msg */
|
||||||
@ -1036,6 +1044,7 @@ in_delmulti(inm)
|
|||||||
if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
|
if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
|
||||||
if (my_inm.inm_ifp != NULL)
|
if (my_inm.inm_ifp != NULL)
|
||||||
igmp_leavegroup(&my_inm);
|
igmp_leavegroup(&my_inm);
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
IN_MULTI_UNLOCK();
|
IN_MULTI_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user