mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-08 05:25:12 +00:00
Make sure that we call if_free(ifp) after bus_teardown_intr. Since we
could get an interrupt after we free the ifp, and the interrupt handler depended on the ifp being still alive, this could, in theory, cause a crash. Eliminate this possibility by moving the if_free to after the bus_teardown_intr() call.
This commit is contained in:
parent
6763e7c1ed
commit
ad4f426ef6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=150306
@ -837,8 +837,8 @@ an_detach(device_t dev)
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
AN_UNLOCK(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
|
||||
if_free(ifp);
|
||||
an_release_resources(dev);
|
||||
mtx_destroy(&sc->an_mtx);
|
||||
return (0);
|
||||
|
@ -324,13 +324,13 @@ arl_isa_detach(device_t dev)
|
||||
|
||||
arl_stop(sc);
|
||||
ifmedia_removeall(&sc->arl_ifmedia);
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
|
||||
#if __FreeBSD_version < 500100
|
||||
ether_ifdetach(sc->arl_ifp, ETHER_BPF_SUPPORTED);
|
||||
#else
|
||||
ether_ifdetach(sc->arl_ifp);
|
||||
if_free(sc->arl_ifp);
|
||||
#endif
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
|
||||
arl_release_resources(dev);
|
||||
|
||||
return (0);
|
||||
|
@ -153,8 +153,7 @@ awi_pccard_attach(device_t dev)
|
||||
|
||||
psc->sc_port_rid = 0;
|
||||
psc->sc_port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
||||
&psc->sc_port_rid, 0, ~0, 16,
|
||||
rman_make_alignment_flags(64) | RF_ACTIVE);
|
||||
&psc->sc_port_rid, 0, ~0, 16, RF_ACTIVE);
|
||||
if (!psc->sc_port_res) {
|
||||
device_printf(dev, "awi_pccard_attach: port alloc failed\n");
|
||||
goto fail;
|
||||
@ -176,7 +175,6 @@ awi_pccard_attach(device_t dev)
|
||||
* XXX: awi needs to access memory with 8bit,
|
||||
* but pccardd apparently maps memory with MDF_16BITS flag.
|
||||
* So memory mapped access is disabled and use IO port instead.
|
||||
* Also, memory mapping is not yet supported on pccard.
|
||||
*/
|
||||
psc->sc_mem_res = 0;
|
||||
#else
|
||||
|
@ -111,10 +111,10 @@ cm_isa_detach(device_t dev)
|
||||
|
||||
s = splimp();
|
||||
arc_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
splx(s);
|
||||
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
|
||||
if_free(ifp);
|
||||
cm_release_resources(dev);
|
||||
|
||||
return (0);
|
||||
|
@ -1599,8 +1599,8 @@ static int cnw_pccard_detach(dev)
|
||||
cnw_stop(sc);
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
cnw_free(dev);
|
||||
if_free(ifp);
|
||||
sc->cnw_gone = 1;
|
||||
|
||||
#if 0
|
||||
|
@ -1438,6 +1438,9 @@ static int cp_detach (device_t dev)
|
||||
cp_reset (b, 0 ,0);
|
||||
callout_stop (&led_timo[b->num]);
|
||||
|
||||
/* Disable the interrupt request. */
|
||||
bus_teardown_intr (dev, bd->cp_irq, bd->cp_intrhand);
|
||||
|
||||
for (c=b->chan; c<b->chan+NCHAN; ++c) {
|
||||
drv_t *d = (drv_t*) c->sys;
|
||||
|
||||
@ -1470,8 +1473,6 @@ static int cp_detach (device_t dev)
|
||||
b->sys = NULL;
|
||||
CP_UNLOCK (bd);
|
||||
|
||||
/* Disable the interrupt request. */
|
||||
bus_teardown_intr (dev, bd->cp_irq, bd->cp_intrhand);
|
||||
bus_deactivate_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq);
|
||||
bus_release_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq);
|
||||
bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->cp_res);
|
||||
|
@ -696,8 +696,8 @@ cs_detach(device_t dev)
|
||||
cs_stop(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
cs_release_resources(dev);
|
||||
if_free(ifp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -369,8 +369,8 @@ ed_detach(device_t dev)
|
||||
callout_drain(&sc->tick_ch);
|
||||
ether_ifdetach(ifp);
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
|
||||
if_free(ifp);
|
||||
ed_release_resources(dev);
|
||||
if_free(ifp);
|
||||
ED_LOCK_DESTROY(sc);
|
||||
return (0);
|
||||
}
|
||||
|
@ -535,10 +535,12 @@ em_detach(device_t dev)
|
||||
ether_ifdetach(adapter->ifp, ETHER_BPF_SUPPORTED);
|
||||
#else
|
||||
ether_ifdetach(adapter->ifp);
|
||||
if_free(ifp);
|
||||
#endif
|
||||
em_free_pci_resources(adapter);
|
||||
bus_generic_detach(dev);
|
||||
#if __FreeBSD_version >= 500000
|
||||
if_free(ifp);
|
||||
#endif
|
||||
|
||||
/* Free Transmit Descriptor ring */
|
||||
if (adapter->tx_desc_base) {
|
||||
|
@ -321,7 +321,6 @@ en_pci_detach(device_t dev)
|
||||
*/
|
||||
en_reset(sc);
|
||||
atm_ifdetach(sc->ifp);
|
||||
if_free(sc->ifp);
|
||||
|
||||
/*
|
||||
* Deallocate resources.
|
||||
@ -334,6 +333,7 @@ en_pci_detach(device_t dev)
|
||||
* Free all the driver internal resources
|
||||
*/
|
||||
en_destroy(sc);
|
||||
if_free(sc->ifp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -360,10 +360,10 @@ ep_detach(device_t dev)
|
||||
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
|
||||
sc->gone = 1;
|
||||
ep_free(dev);
|
||||
if_free(ifp);
|
||||
EP_LOCK_DESTROY(sc);
|
||||
|
||||
return (0);
|
||||
|
@ -187,8 +187,8 @@ fe_pccard_detach(device_t dev)
|
||||
|
||||
fe_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
|
||||
if_free(ifp);
|
||||
fe_release_resource(dev);
|
||||
|
||||
return 0;
|
||||
|
@ -885,8 +885,6 @@ ndis_detach(dev)
|
||||
ether_ifdetach(ifp);
|
||||
} else
|
||||
NDIS_UNLOCK(sc);
|
||||
if (ifp != NULL)
|
||||
if_free(ifp);
|
||||
|
||||
bus_generic_detach(dev);
|
||||
|
||||
@ -904,6 +902,9 @@ ndis_detach(dev)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
sc->ndis_altmem_rid, sc->ndis_res_altmem);
|
||||
|
||||
if (ifp != NULL)
|
||||
if_free(ifp);
|
||||
|
||||
if (sc->ndis_iftype == PCMCIABus)
|
||||
ndis_free_amem(sc);
|
||||
|
||||
|
@ -391,7 +391,6 @@ ipw_detach(device_t dev)
|
||||
if (ifp != NULL) {
|
||||
bpfdetach(ifp);
|
||||
ieee80211_ifdetach(ic);
|
||||
if_free(ifp);
|
||||
}
|
||||
|
||||
ipw_release(sc);
|
||||
@ -403,6 +402,8 @@ ipw_detach(device_t dev)
|
||||
|
||||
if (sc->mem != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
|
||||
if (ifp != NULL)
|
||||
if_free(ifp);
|
||||
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
||||
|
@ -467,7 +467,6 @@ iwi_detach(device_t dev)
|
||||
if (ifp != NULL) {
|
||||
bpfdetach(ifp);
|
||||
ieee80211_ifdetach(ic);
|
||||
if_free(ifp);
|
||||
}
|
||||
|
||||
iwi_free_cmd_ring(sc, &sc->cmdq);
|
||||
@ -485,6 +484,8 @@ iwi_detach(device_t dev)
|
||||
if (sc->mem != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
|
||||
|
||||
if (ifp != NULL)
|
||||
if_free(ifp);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
||||
return 0;
|
||||
|
@ -378,10 +378,11 @@ ixgb_detach(device_t dev)
|
||||
ether_ifdetach(adapter->ifp, ETHER_BPF_SUPPORTED);
|
||||
#else
|
||||
ether_ifdetach(adapter->ifp);
|
||||
if_free(adapter->ifp);
|
||||
#endif
|
||||
ixgb_free_pci_resources(adapter);
|
||||
|
||||
#if __FreeBSD_version >= 500000
|
||||
if_free(adapter->ifp);
|
||||
#endif
|
||||
|
||||
/* Free Transmit Descriptor ring */
|
||||
if (adapter->tx_desc_base) {
|
||||
|
@ -627,7 +627,6 @@ lge_detach(dev)
|
||||
lge_reset(sc);
|
||||
lge_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->lge_miibus);
|
||||
@ -637,6 +636,7 @@ lge_detach(dev)
|
||||
bus_release_resource(dev, LGE_RES, LGE_RID, sc->lge_res);
|
||||
|
||||
contigfree(sc->lge_ldata, sizeof(struct lge_list_data), M_DEVBUF);
|
||||
if_free(ifp);
|
||||
lge_free_jumbo_mem(sc);
|
||||
|
||||
splx(s);
|
||||
|
@ -963,7 +963,6 @@ nge_detach(dev)
|
||||
nge_stop(sc);
|
||||
NGE_UNLOCK(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
|
||||
bus_generic_detach(dev);
|
||||
if (!sc->nge_tbi) {
|
||||
@ -974,6 +973,7 @@ nge_detach(dev)
|
||||
bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res);
|
||||
|
||||
contigfree(sc->nge_ldata, sizeof(struct nge_list_data), M_DEVBUF);
|
||||
if_free(ifp);
|
||||
|
||||
NGE_LOCK_DESTROY(sc);
|
||||
|
||||
|
@ -559,12 +559,10 @@ nve_detach(device_t dev)
|
||||
|
||||
if (device_is_attached(dev)) {
|
||||
nve_stop(sc);
|
||||
/* XXX shouldn't hold lock over call to ether_ifdetch */
|
||||
ether_ifdetach(ifp);
|
||||
}
|
||||
|
||||
if (ifp)
|
||||
if_free(ifp);
|
||||
|
||||
if (sc->miibus)
|
||||
device_delete_child(dev, sc->miibus);
|
||||
bus_generic_detach(dev);
|
||||
@ -601,6 +599,8 @@ nve_detach(device_t dev)
|
||||
bus_dma_tag_destroy(sc->rtag);
|
||||
|
||||
NVE_UNLOCK(sc);
|
||||
if (ifp)
|
||||
if_free(ifp);
|
||||
mtx_destroy(&sc->mtx);
|
||||
mtx_destroy(&sc->osmtx);
|
||||
|
||||
|
@ -531,7 +531,6 @@ ral_detach(device_t dev)
|
||||
|
||||
bpfdetach(ifp);
|
||||
ieee80211_ifdetach(ic);
|
||||
if_free(ifp);
|
||||
|
||||
ral_free_tx_ring(sc, &sc->txq);
|
||||
ral_free_tx_ring(sc, &sc->atimq);
|
||||
@ -540,6 +539,7 @@ ral_detach(device_t dev)
|
||||
ral_free_rx_ring(sc, &sc->rxq);
|
||||
|
||||
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
|
||||
if_free(ifp);
|
||||
ral_free(dev);
|
||||
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
@ -604,7 +604,6 @@ ray_detach(device_t dev)
|
||||
sc->sc_c.np_havenet = 0;
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
|
||||
/*
|
||||
* Stop the runq and wake up anyone sleeping for us.
|
||||
@ -627,6 +626,7 @@ ray_detach(device_t dev)
|
||||
* Release resources
|
||||
*/
|
||||
ray_res_release(sc);
|
||||
if_free(ifp);
|
||||
RAY_DPRINTF(sc, RAY_DBG_STOP, "unloading complete");
|
||||
|
||||
splx(s);
|
||||
|
@ -1303,10 +1303,10 @@ re_detach(dev)
|
||||
* stopped here.
|
||||
*/
|
||||
|
||||
if (ifp != NULL)
|
||||
if_free(ifp);
|
||||
if (sc->rl_intrhand)
|
||||
bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
|
||||
if (ifp != NULL)
|
||||
if_free(ifp);
|
||||
if (sc->rl_irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
|
||||
if (sc->rl_res)
|
||||
|
@ -311,12 +311,13 @@ sbsh_detach(device_t dev)
|
||||
|
||||
sbsh_stop(sc);
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
|
||||
bus_teardown_intr(dev, sc->irq_res, sc->intr_hand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(1), sc->mem_res);
|
||||
|
||||
if_free(ifp);
|
||||
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
@ -44,23 +44,15 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/sio/siovar.h>
|
||||
|
||||
#include "pccarddevs.h"
|
||||
|
||||
static int sio_pccard_attach(device_t dev);
|
||||
static int sio_pccard_match(device_t self);
|
||||
static int sio_pccard_probe(device_t dev);
|
||||
|
||||
static device_method_t sio_pccard_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, pccard_compat_probe),
|
||||
DEVMETHOD(device_attach, pccard_compat_attach),
|
||||
DEVMETHOD(device_probe, sio_pccard_probe),
|
||||
DEVMETHOD(device_attach, sio_pccard_attach),
|
||||
DEVMETHOD(device_detach, siodetach),
|
||||
|
||||
/* Card interface */
|
||||
DEVMETHOD(card_compat_match, sio_pccard_match),
|
||||
DEVMETHOD(card_compat_probe, sio_pccard_probe),
|
||||
DEVMETHOD(card_compat_attach, sio_pccard_attach),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -71,7 +63,7 @@ static driver_t sio_pccard_driver = {
|
||||
};
|
||||
|
||||
static int
|
||||
sio_pccard_match(device_t dev)
|
||||
sio_pccard_probe(device_t dev)
|
||||
{
|
||||
int error = 0;
|
||||
u_int32_t fcn = PCCARD_FUNCTION_UNSPEC;
|
||||
@ -79,6 +71,7 @@ sio_pccard_match(device_t dev)
|
||||
error = pccard_get_function(dev, &fcn);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* If a serial card, we are likely the right driver. However,
|
||||
* some serial cards are better servered by other drivers, so
|
||||
@ -86,27 +79,22 @@ sio_pccard_match(device_t dev)
|
||||
*/
|
||||
if (fcn == PCCARD_FUNCTION_SERIAL)
|
||||
return (-100);
|
||||
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
sio_pccard_probe(dev)
|
||||
device_t dev;
|
||||
{
|
||||
|
||||
#ifdef PC98
|
||||
SET_FLAG(dev, SET_IFTYPE(COM_IF_MODEM_CARD));
|
||||
#endif
|
||||
/* Do not probe IRQ - pccard doesn't turn on the interrupt line */
|
||||
/* until bus_setup_intr */
|
||||
return (sioprobe(dev, 0, 0UL, 1));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
sio_pccard_attach(dev)
|
||||
device_t dev;
|
||||
{
|
||||
int err;
|
||||
|
||||
#ifdef PC98
|
||||
SET_FLAG(dev, SET_IFTYPE(COM_IF_MODEM_CARD));
|
||||
#endif
|
||||
/* Do not probe IRQ - pccard doesn't turn on the interrupt line */
|
||||
/* until bus_setup_intr */
|
||||
if ((err = sioprobe(dev, 0, 0UL, 1)) != 0)
|
||||
return (err);
|
||||
return (sioattach(dev, 0, 0UL));
|
||||
}
|
||||
|
||||
|
@ -233,8 +233,8 @@ sn_detach(device_t dev)
|
||||
snstop(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
sn_deactivate(dev);
|
||||
if_free(ifp);
|
||||
SN_LOCK_DESTROY(sc);
|
||||
return 0;
|
||||
}
|
||||
|
@ -446,7 +446,6 @@ fail:
|
||||
static void
|
||||
epic_release(epic_softc_t *sc)
|
||||
{
|
||||
|
||||
if (sc->ifp != NULL)
|
||||
if_free(sc->ifp);
|
||||
if (sc->irq)
|
||||
|
@ -392,9 +392,6 @@ txp_release_resources(sc)
|
||||
|
||||
dev = sc->sc_dev;
|
||||
|
||||
if (sc->sc_ifp)
|
||||
if_free(sc->sc_ifp);
|
||||
|
||||
if (sc->sc_intrhand != NULL)
|
||||
bus_teardown_intr(dev, sc->sc_irq, sc->sc_intrhand);
|
||||
|
||||
@ -407,6 +404,9 @@ txp_release_resources(sc)
|
||||
if (sc->sc_ldata != NULL)
|
||||
contigfree(sc->sc_ldata, sizeof(struct txp_ldata), M_DEVBUF);
|
||||
|
||||
if (sc->sc_ifp)
|
||||
if_free(sc->sc_ifp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1123,8 +1123,6 @@ vge_detach(dev)
|
||||
ifp->if_flags &= ~IFF_UP;
|
||||
ether_ifdetach(ifp);
|
||||
}
|
||||
if (ifp)
|
||||
if_free(ifp);
|
||||
if (sc->vge_miibus)
|
||||
device_delete_child(dev, sc->vge_miibus);
|
||||
bus_generic_detach(dev);
|
||||
@ -1136,6 +1134,8 @@ vge_detach(dev)
|
||||
if (sc->vge_res)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
VGE_PCI_LOMEM, sc->vge_res);
|
||||
if (ifp)
|
||||
if_free(ifp);
|
||||
|
||||
/* Unload and free the RX DMA ring memory and map */
|
||||
|
||||
|
@ -534,9 +534,9 @@ wi_detach(device_t dev)
|
||||
bpfdetach(ifp);
|
||||
#endif
|
||||
ieee80211_ifdetach(&sc->sc_ic);
|
||||
if_free(sc->sc_ifp);
|
||||
WI_UNLOCK(sc);
|
||||
bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
|
||||
if_free(sc->sc_ifp);
|
||||
wi_free(dev);
|
||||
#if __FreeBSD_version >= 500000
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
@ -589,7 +589,6 @@ wldetach(device_t device)
|
||||
|
||||
ifp = sc->ifp;
|
||||
ether_ifdetach(ifp);
|
||||
if_free(ifp);
|
||||
|
||||
WL_LOCK(sc);
|
||||
|
||||
@ -607,6 +606,7 @@ wldetach(device_t device)
|
||||
bus_generic_detach(device);
|
||||
wl_deallocate_resources(device);
|
||||
WL_UNLOCK(sc);
|
||||
if_free(ifp);
|
||||
mtx_destroy(&sc->wl_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
@ -328,8 +328,8 @@ xe_pccard_detach(device_t dev)
|
||||
|
||||
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
ether_ifdetach(sc->ifp);
|
||||
if_free(sc->ifp);
|
||||
xe_deactivate(dev);
|
||||
if_free(sc->ifp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user