diff options
author | Andrew Thompson <thompsa@FreeBSD.org> | 2005-10-12 19:52:16 +0000 |
---|---|---|
committer | Andrew Thompson <thompsa@FreeBSD.org> | 2005-10-12 19:52:16 +0000 |
commit | febd0759f34e2faaaed0abf5fafb1071090aef38 (patch) | |
tree | e685414c2d4a9a0e96a99f9d18fa6ce3780a6fbe /sys/net/if_ppp.c | |
parent | 680d937a4bf3a6c79bdebd02f25dc976834df0c7 (diff) | |
download | src-febd0759f34e2faaaed0abf5fafb1071090aef38.tar.gz src-febd0759f34e2faaaed0abf5fafb1071090aef38.zip |
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
Notes
Notes:
svn path=/head/; revision=151266
Diffstat (limited to 'sys/net/if_ppp.c')
-rw-r--r-- | sys/net/if_ppp.c | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index a4bb60cc63f2..45915c6b8e1a 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -242,11 +242,15 @@ ppp_clone_create(struct if_clone *ifc, int unit) } static void -ppp_destroy(struct ppp_softc *sc) +ppp_clone_destroy(struct ifnet *ifp) { - struct ifnet *ifp; + struct ppp_softc *sc; + + sc = ifp->if_softc; + PPP_LIST_LOCK(); + LIST_REMOVE(sc, sc_list); + PPP_LIST_UNLOCK(); - ifp = PPP2IFP(sc); bpfdetach(ifp); if_detach(ifp); if_free(ifp); @@ -256,18 +260,6 @@ ppp_destroy(struct ppp_softc *sc) free(sc, M_PPP); } -static void -ppp_clone_destroy(struct ifnet *ifp) -{ - struct ppp_softc *sc; - - sc = ifp->if_softc; - PPP_LIST_LOCK(); - LIST_REMOVE(sc, sc_list); - PPP_LIST_UNLOCK(); - ppp_destroy(sc); -} - static int ppp_modevent(module_t mod, int type, void *data) { @@ -296,9 +288,8 @@ ppp_modevent(module_t mod, int type, void *data) PPP_LIST_LOCK(); while ((sc = LIST_FIRST(&ppp_softc_list)) != NULL) { - LIST_REMOVE(sc, sc_list); PPP_LIST_UNLOCK(); - ppp_destroy(sc); + ifc_simple_destroy(&ppp_cloner, PPP2IFP(sc)); PPP_LIST_LOCK(); } PPP_LIST_LOCK_DESTROY(); |