Преглед изворни кода

[PATCH] hostap: Do not free local->hw_priv before unregistering netdev

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>
Jouni Malinen пре 19 година
родитељ
комит
c355184cd3

+ 3 - 2
drivers/net/wireless/hostap/hostap_cs.c

@@ -565,13 +565,14 @@ static void prism2_detach(dev_link_t *link)
 	*linkp = link->next;
 	*linkp = link->next;
 	/* release net devices */
 	/* release net devices */
 	if (link->priv) {
 	if (link->priv) {
+		struct hostap_cs_priv *hw_priv;
 		struct net_device *dev;
 		struct net_device *dev;
 		struct hostap_interface *iface;
 		struct hostap_interface *iface;
 		dev = link->priv;
 		dev = link->priv;
 		iface = netdev_priv(dev);
 		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);
 		prism2_free_local_data(dev);
+		kfree(hw_priv);
 	}
 	}
 	kfree(link);
 	kfree(link);
 }
 }

+ 2 - 7
drivers/net/wireless/hostap/hostap_pci.c

@@ -358,8 +358,6 @@ static int prism2_pci_probe(struct pci_dev *pdev,
 	return hostap_hw_ready(dev);
 	return hostap_hw_ready(dev);
 
 
  fail:
  fail:
-	kfree(hw_priv);
-
 	if (irq_registered && dev)
 	if (irq_registered && dev)
 		free_irq(dev->irq, dev);
 		free_irq(dev->irq, dev);
 
 
@@ -370,10 +368,8 @@ static int prism2_pci_probe(struct pci_dev *pdev,
 
 
  err_out_disable:
  err_out_disable:
 	pci_disable_device(pdev);
 	pci_disable_device(pdev);
-	kfree(hw_priv);
-	if (local)
-		local->hw_priv = NULL;
 	prism2_free_local_data(dev);
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 
 
 	return -ENODEV;
 	return -ENODEV;
 }
 }
@@ -398,9 +394,8 @@ static void prism2_pci_remove(struct pci_dev *pdev)
 		free_irq(dev->irq, dev);
 		free_irq(dev->irq, dev);
 
 
 	mem_start = hw_priv->mem_start;
 	mem_start = hw_priv->mem_start;
-	kfree(hw_priv);
-	iface->local->hw_priv = NULL;
 	prism2_free_local_data(dev);
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 
 
 	iounmap(mem_start);
 	iounmap(mem_start);
 
 

+ 2 - 5
drivers/net/wireless/hostap/hostap_plx.c

@@ -568,10 +568,8 @@ static int prism2_plx_probe(struct pci_dev *pdev,
 	return hostap_hw_ready(dev);
 	return hostap_hw_ready(dev);
 
 
  fail:
  fail:
-	kfree(hw_priv);
-	if (local)
-		local->hw_priv = NULL;
 	prism2_free_local_data(dev);
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 
 
 	if (irq_registered && dev)
 	if (irq_registered && dev)
 		free_irq(dev->irq, dev);
 		free_irq(dev->irq, dev);
@@ -604,9 +602,8 @@ static void prism2_plx_remove(struct pci_dev *pdev)
 	if (dev->irq)
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 		free_irq(dev->irq, dev);
 
 
-	kfree(iface->local->hw_priv);
-	iface->local->hw_priv = NULL;
 	prism2_free_local_data(dev);
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 	pci_disable_device(pdev);
 	pci_disable_device(pdev);
 }
 }