diff options
author | thompsa <thompsa@FreeBSD.org> | 2005-10-12 19:52:16 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2005-10-12 19:52:16 +0000 |
commit | d6130a47038460d2093bdc0fcdadd546393cc823 (patch) | |
tree | e685414c2d4a9a0e96a99f9d18fa6ce3780a6fbe /sys/net/if_faith.c | |
parent | 1917bf7b66cadbb6cbcc022f50fb4252b6996ff7 (diff) | |
download | FreeBSD-src-d6130a47038460d2093bdc0fcdadd546393cc823.zip FreeBSD-src-d6130a47038460d2093bdc0fcdadd546393cc823.tar.gz |
Change the reference counting to count the number of cloned interfaces for each
cloner. This ensures that ifc->ifc_units is not prematurely freed in
if_clone_detach() before the clones are destroyed, resulting in memory modified
after free. This could be triggered with if_vlan.
Assert that all cloners have been destroyed when freeing the memory.
Change all simple cloners to destroy their clones with ifc_simple_destroy() on
module unload so the reference count is properly updated. This also cleans up
the interface destroy routines and allows future optimisation.
Discussed with: brooks, pjd, -current
Reviewed by: brooks
Diffstat (limited to 'sys/net/if_faith.c')
-rw-r--r-- | sys/net/if_faith.c | 19 |
1 files changed, 5 insertions, 14 deletions
diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index d71a3fa..677e1b2 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -103,7 +103,6 @@ static LIST_HEAD(, faith_softc) faith_softc_list; static int faith_clone_create(struct if_clone *, int); static void faith_clone_destroy(struct ifnet *); -static void faith_destroy(struct faith_softc *); IFC_SIMPLE_DECLARE(faith, 0); @@ -137,9 +136,8 @@ faithmodevent(mod, type, data) mtx_lock(&faith_mtx); while ((sc = LIST_FIRST(&faith_softc_list)) != NULL) { - LIST_REMOVE(sc, sc_list); mtx_unlock(&faith_mtx); - faith_destroy(sc); + ifc_simple_destroy(&faith_cloner, sc->sc_ifp); mtx_lock(&faith_mtx); } mtx_unlock(&faith_mtx); @@ -195,16 +193,6 @@ faith_clone_create(ifc, unit) } static void -faith_destroy(struct faith_softc *sc) -{ - - bpfdetach(sc->sc_ifp); - if_detach(sc->sc_ifp); - if_free(sc->sc_ifp); - free(sc, M_FAITH); -} - -static void faith_clone_destroy(ifp) struct ifnet *ifp; { @@ -214,7 +202,10 @@ faith_clone_destroy(ifp) LIST_REMOVE(sc, sc_list); mtx_unlock(&faith_mtx); - faith_destroy(sc); + bpfdetach(ifp); + if_detach(ifp); + if_free(ifp); + free(sc, M_FAITH); } int |