Don't call enable_all_rings if the adapter has been freed.

This is a subtle use-after-free race that results in some very undesirable
hang behaviour.

Reviewed by:	pkelsey
Obtained from:	Kip Macy, NextBSD (91a9bd1dbb)
This commit is contained in:
adrian 2015-09-07 23:16:39 +00:00
parent db20d88fda
commit c5bfe674df

View File

@ -2841,10 +2841,12 @@ void
netmap_detach(struct ifnet *ifp)
{
struct netmap_adapter *na = NA(ifp);
int skip;
if (!na)
return;
skip = 0;
NMG_LOCK();
netmap_disable_all_rings(ifp);
na->ifp = NULL;
@ -2856,10 +2858,11 @@ netmap_detach(struct ifnet *ifp)
* the driver is gone.
*/
if (na->na_flags & NAF_NATIVE) {
netmap_adapter_put(na);
skip = netmap_adapter_put(na);
}
/* give them a chance to notice */
netmap_enable_all_rings(ifp);
if (skip == 0)
netmap_enable_all_rings(ifp);
NMG_UNLOCK();
}