Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c355184c authored by Jouni Malinen's avatar Jouni Malinen Committed by Jeff Garzik
Browse files

[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: default avatarJouni Malinen <jkmaline@cc.hut.fi>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent f7a74447
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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);
}
+2 −7
Original line number Diff line number Diff line
@@ -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);

+2 −5
Original line number Diff line number Diff line
@@ -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);
}