aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/marvell/mwifiex/pcie.c
diff options
context:
space:
mode:
authorBrian Norris <briannorris@chromium.org>2017-03-28 16:59:33 -0700
committerKalle Valo <kvalo@codeaurora.org>2017-04-05 15:44:04 +0300
commit755b37c93a069ff0882411630a06e90b3193d092 (patch)
tree83d34d390fe620f70cb6ead4971c4486913da750 /drivers/net/wireless/marvell/mwifiex/pcie.c
parentmwifiex: fix use-after-free for FW reinit errors (diff)
downloadlinux-dev-755b37c93a069ff0882411630a06e90b3193d092.tar.xz
linux-dev-755b37c93a069ff0882411630a06e90b3193d092.zip
mwifiex: catch mwifiex_fw_dpc() errors properly in reset
When resetting the device, we take a synchronous firmware-loading code path, which borrows a lot from the asynchronous path used at probe time. We don't catch errors correctly though, which means that in the PCIe driver, we may try to dereference the 'adapter' struct after mwifiex_fw_dpc() has freed it. See this (erronous) print in mwifiex_pcie_reset_notify(): mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); Let's instead refactor the synchronous (or "!req_fw_nowait") path so that we propagate errors and handle them properly. This fixes a use-after-free issue in the PCIe driver, as well as a misleading debug message ("successful"). It looks like the SDIO driver doesn't have these problems, since it doesn't do anything after mwifiex_reinit_sw(). Fixes: 4c5dae59d2e9 ("mwifiex: add PCIe function level reset support") Signed-off-by: Brian Norris <briannorris@chromium.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/pcie.c')
-rw-r--r--drivers/net/wireless/marvell/mwifiex/pcie.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index e381deff37f3..f45ab125cd0d 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -350,6 +350,7 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
{
struct pcie_service_card *card = pci_get_drvdata(pdev);
struct mwifiex_adapter *adapter = card->adapter;
+ int ret;
if (!adapter) {
dev_err(&pdev->dev, "%s: adapter structure is not valid\n",
@@ -376,7 +377,11 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
* and firmware including firmware redownload
*/
adapter->surprise_removed = false;
- mwifiex_reinit_sw(adapter);
+ ret = mwifiex_reinit_sw(adapter);
+ if (ret) {
+ dev_err(&pdev->dev, "reinit failed: %d\n", ret);
+ return;
+ }
}
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}