Commit ce32d1d8 authored by Brian Norris's avatar Brian Norris Committed by Kalle Valo

mwifiex: unregister wiphy before freeing resources

It's possible for some control interfaces (e.g., scans, set freq) to be
active after we've stopped our main work queue and the netif TX queues.
These don't get completely shut out until we've unregistered the wdevs
and wiphy.

So let's only free command buffers and poison our lists after
wiphy_unregister().

This resolves various use-after-free issues seen when resetting the
device.

Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 643acea6
......@@ -418,7 +418,10 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
mwifiex_cancel_all_pending_cmd(adapter);
wake_up_interruptible(&adapter->cmd_wait_q.wait);
wake_up_interruptible(&adapter->hs_activate_wait_q);
}
void mwifiex_free_cmd_buffers(struct mwifiex_adapter *adapter)
{
/* Free lock variables */
mwifiex_free_lock_list(adapter);
......
......@@ -653,6 +653,7 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context)
if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
pr_debug("info: %s: shutdown mwifiex\n", __func__);
mwifiex_shutdown_drv(adapter);
mwifiex_free_cmd_buffers(adapter);
}
init_failed = true;
......@@ -1404,11 +1405,13 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter)
mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
rtnl_unlock();
}
vfree(adapter->chan_stats);
wiphy_unregister(adapter->wiphy);
wiphy_free(adapter->wiphy);
adapter->wiphy = NULL;
vfree(adapter->chan_stats);
mwifiex_free_cmd_buffers(adapter);
}
/*
......@@ -1515,6 +1518,7 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
mwifiex_dbg(adapter, ERROR,
"info: %s: shutdown mwifiex\n", __func__);
mwifiex_shutdown_drv(adapter);
mwifiex_free_cmd_buffers(adapter);
}
complete_all(adapter->fw_done);
......@@ -1662,6 +1666,7 @@ mwifiex_add_card(void *card, struct completion *fw_done,
if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
pr_debug("info: %s: shutdown mwifiex\n", __func__);
mwifiex_shutdown_drv(adapter);
mwifiex_free_cmd_buffers(adapter);
}
err_kmalloc:
mwifiex_free_adapter(adapter);
......
......@@ -1078,6 +1078,7 @@ int mwifiex_get_debug_info(struct mwifiex_private *,
int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter);
int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter);
void mwifiex_free_cmd_buffers(struct mwifiex_adapter *adapter);
void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter);
void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter);
void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment