[PATCH] hostap: Do not free local->hw_priv before unregistering netdev
authorJouni Malinen <jkmaline@cc.hut.fi>
Mon, 3 Oct 2005 00:19:00 +0000 (17:19 -0700)
committerJeff Garzik <jgarzik@pobox.com>
Tue, 4 Oct 2005 02:00:08 +0000 (22:00 -0400)
local->hw_priv was being freed and set to NULL just before calling
prism2_free_local_data(). However, this may expose a race condition in
which something ends up trying to use hw_priv during shutdown. I
haven't noticed this happening, but better be safe than sorry, so
let's postpone hw_priv freeing to happen only after
prism2_free_local_data() has returned.

Signed-off-by: Jouni Malinen <jkmaline@cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/hostap/hostap_pci.c
drivers/net/wireless/hostap/hostap_plx.c

index 23bcc51b713170f928618131176ca8ef4c2d587d..2643976a66775f559936b4fd0ce84672d96342d2 100644 (file)
@@ -565,13 +565,14 @@ static void prism2_detach(dev_link_t *link)
        *linkp = link->next;
        /* release net devices */
        if (link->priv) {
+               struct hostap_cs_priv *hw_priv;
                struct net_device *dev;
                struct hostap_interface *iface;
                dev = link->priv;
                iface = netdev_priv(dev);
-               kfree(iface->local->hw_priv);
-               iface->local->hw_priv = NULL;
+               hw_priv = iface->local->hw_priv;
                prism2_free_local_data(dev);
+               kfree(hw_priv);
        }
        kfree(link);
 }
index 0d7305dfa6903a590370425c13e1a4596e27ca1a..da0c80fb941cab99dac9d2c93cf0105010f90abd 100644 (file)
@@ -358,8 +358,6 @@ static int prism2_pci_probe(struct pci_dev *pdev,
        return hostap_hw_ready(dev);
 
  fail:
-       kfree(hw_priv);
-
        if (irq_registered && dev)
                free_irq(dev->irq, dev);
 
@@ -370,10 +368,8 @@ static int prism2_pci_probe(struct pci_dev *pdev,
 
  err_out_disable:
        pci_disable_device(pdev);
-       kfree(hw_priv);
-       if (local)
-               local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
 
        return -ENODEV;
 }
@@ -398,9 +394,8 @@ static void prism2_pci_remove(struct pci_dev *pdev)
                free_irq(dev->irq, dev);
 
        mem_start = hw_priv->mem_start;
-       kfree(hw_priv);
-       iface->local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
 
        iounmap(mem_start);
 
index 85d3f8a29539ca47e07c407cb34c1fcd684f6012..78d67b408b2f9423080bd276ba4bfc78644164a7 100644 (file)
@@ -568,10 +568,8 @@ static int prism2_plx_probe(struct pci_dev *pdev,
        return hostap_hw_ready(dev);
 
  fail:
-       kfree(hw_priv);
-       if (local)
-               local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
 
        if (irq_registered && dev)
                free_irq(dev->irq, dev);
@@ -604,9 +602,8 @@ static void prism2_plx_remove(struct pci_dev *pdev)
        if (dev->irq)
                free_irq(dev->irq, dev);
 
-       kfree(iface->local->hw_priv);
-       iface->local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
        pci_disable_device(pdev);
 }