From ac6076ce76398b1099503714ff1afd7e0a332d4c Mon Sep 17 00:00:00 2001 From: sruffell Date: Wed, 2 Jan 2008 15:20:56 +0000 Subject: Move the release of VPMADT032 resources to after the interrupt handler has been freed. Closes a small window of opportunity for NULL pointer access at driver unload time. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@3586 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wctdm24xxp/base.c | 20 ++++++++++++-------- wcte12xp/base.c | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/wctdm24xxp/base.c b/wctdm24xxp/base.c index 14dabe3..208579c 100644 --- a/wctdm24xxp/base.c +++ b/wctdm24xxp/base.c @@ -4238,21 +4238,16 @@ static void __devexit wctdm_remove_one(struct pci_dev *pdev) #endif if (wc) { + #ifdef VPM150M_SUPPORT if (vpm150m) { clear_bit(VPM150M_DTMFDETECT, &vpm150m->control); clear_bit(VPM150M_ACTIVE, &vpm150m->control); flush_workqueue(vpm150m->wq); destroy_workqueue(vpm150m->wq); - - spin_lock_irqsave(&wc->reglock, flags); - wc->vpm150m = NULL; - vpm150m->wc = NULL; - spin_unlock_irqrestore(&wc->reglock, flags); - - kfree(wc->vpm150m); } #endif + /* Stop any DMA */ wctdm_stop_dma(wc); @@ -4260,9 +4255,18 @@ static void __devexit wctdm_remove_one(struct pci_dev *pdev) wctdm_disable_interrupts(wc); /* Immediately free resources */ - pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma); free_irq(pdev->irq, wc); + pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma); +#ifdef VPM150M_SUPPORT + if (vpm150m) { + spin_lock_irqsave(&wc->reglock, flags); + wc->vpm150m = NULL; + vpm150m->wc = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + kfree(wc->vpm150m); + } +#endif /* Release span, possibly delayed */ if (!wc->usecount) wctdm_release(wc); diff --git a/wcte12xp/base.c b/wcte12xp/base.c index 5990892..89272c0 100644 --- a/wcte12xp/base.c +++ b/wcte12xp/base.c @@ -1973,7 +1973,6 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev) #ifdef VPM_SUPPORT struct vpm150m *vpm150m = wc->vpm150m; #endif - if (!wc) return; @@ -1983,16 +1982,8 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev) clear_bit(VPM150M_ACTIVE, &vpm150m->control); flush_workqueue(vpm150m->wq); destroy_workqueue(vpm150m->wq); - - kfree(wc->vpm150m); - - spin_lock_irqsave(&wc->reglock, flags); - wc->vpm150m = NULL; - vpm150m->wc = NULL; - spin_unlock_irqrestore(&wc->reglock, flags); } #endif - /* Stop any DMA */ t1_stop_dma(wc); @@ -2003,9 +1994,18 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev) debug_printk(1, "isrreaderrors=%d\n", wc->isrreaderrors); /* Immediately free resources */ - pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma); free_irq(pdev->irq, wc); - + pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma); + +#ifdef VPM_SUPPORT + if(vpm150m) { + spin_lock_irqsave(&wc->reglock, flags); + wc->vpm150m = NULL; + vpm150m->wc = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + kfree(wc->vpm150m); + } +#endif /* Release span, possibly delayed */ if (!wc->usecount) t1_release(wc); -- cgit v1.2.3