diff options
author | ru <ru@FreeBSD.org> | 2005-09-15 18:59:34 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2005-09-15 18:59:34 +0000 |
commit | 3d19005d33ac59832be65b17d5419bc9e80ab156 (patch) | |
tree | b7093cc58755d83340e23766a26cad62368cba81 /sys/dev | |
parent | 96a74ed6d2d1d7673ad0e354a7224e2468151c6b (diff) | |
download | FreeBSD-src-3d19005d33ac59832be65b17d5419bc9e80ab156.zip FreeBSD-src-3d19005d33ac59832be65b17d5419bc9e80ab156.tar.gz |
re_detach() fixes:
- Fixed if_free() logic screw-up that can either result
in freeing a NULL pointer or leaking "struct ifnet".
- Move if_free() after re_stop(); the latter accesses
"struct ifnet". This bug was masked by a previous bug.
- Restore the fix for a panic on detach caused by racing
with BPF detach code by Bill by moving ether_ifdetach()
after re_stop() and resetting IFF_UP; this got screwed
up in revs. 1.30 and 1.36.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/re/if_re.c | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index f9f0e0f..5f09ff2 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -1234,7 +1234,6 @@ re_attach(dev) printf("re%d: attach aborted due to hardware diag failure\n", unit); ether_ifdetach(ifp); - if_free(ifp); goto fail; } @@ -1244,7 +1243,6 @@ re_attach(dev) if (error) { printf("re%d: couldn't set up irq\n", unit); ether_ifdetach(ifp); - if_free(ifp); } fail: @@ -1268,27 +1266,19 @@ re_detach(dev) struct rl_softc *sc; struct ifnet *ifp; int i; - int attached; sc = device_get_softc(dev); ifp = sc->rl_ifp; KASSERT(mtx_initialized(&sc->rl_mtx), ("re mutex not initialized")); - attached = device_is_attached(dev); /* These should only be active if attach succeeded */ - if (attached) - ether_ifdetach(ifp); - if (ifp == NULL) - if_free(ifp); - - RL_LOCK(sc); + if (device_is_attached(dev)) { + RL_LOCK(sc); #if 0 - sc->suspended = 1; + sc->suspended = 1; #endif - - /* These should only be active if attach succeeded */ - if (attached) { re_stop(sc); + RL_UNLOCK(sc); /* * Force off the IFF_UP flag here, in case someone * still had a BPF descriptor attached to this @@ -1302,6 +1292,7 @@ re_detach(dev) * anymore. */ ifp->if_flags &= ~IFF_UP; + ether_ifdetach(ifp); } if (sc->rl_miibus) device_delete_child(dev, sc->rl_miibus); @@ -1311,8 +1302,9 @@ re_detach(dev) * The rest is resource deallocation, so we should already be * stopped here. */ - RL_UNLOCK(sc); + if (ifp != NULL) + if_free(ifp); if (sc->rl_intrhand) bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand); if (sc->rl_irq) |