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_gif.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_gif.c')
-rw-r--r-- | sys/net/if_gif.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 7b01bbb..da611cc 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -186,10 +186,15 @@ gifattach0(sc) } static void -gif_destroy(struct gif_softc *sc) +gif_clone_destroy(ifp) + struct ifnet *ifp; { - struct ifnet *ifp = GIF2IFP(sc); int err; + struct gif_softc *sc = ifp->if_softc; + + mtx_lock(&gif_mtx); + LIST_REMOVE(sc, gif_list); + mtx_unlock(&gif_mtx); gif_delete_tunnel(ifp); #ifdef INET6 @@ -214,18 +219,6 @@ gif_destroy(struct gif_softc *sc) free(sc, M_GIF); } -static void -gif_clone_destroy(ifp) - struct ifnet *ifp; -{ - struct gif_softc *sc = ifp->if_softc; - - mtx_lock(&gif_mtx); - LIST_REMOVE(sc, gif_list); - mtx_unlock(&gif_mtx); - gif_destroy(sc); -} - static int gifmodevent(mod, type, data) module_t mod; @@ -250,9 +243,8 @@ gifmodevent(mod, type, data) mtx_lock(&gif_mtx); while ((sc = LIST_FIRST(&gif_softc_list)) != NULL) { - LIST_REMOVE(sc, gif_list); mtx_unlock(&gif_mtx); - gif_destroy(sc); + ifc_simple_destroy(&gif_cloner, GIF2IFP(sc)); mtx_lock(&gif_mtx); } mtx_unlock(&gif_mtx); |