Commit 16d25da9 authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by Kalle Valo

mwifiex: fix NULL pointer dereference during suspend

This patch fixes below NULL pointer dereference observed in suspend
stress test. When scan is cancelled during system suspend, we may end
up aceesing "priv->scan_request" in corner case.

[ 3035.304682] BUG: KASAN: null-ptr-deref on address 0000000000000008
[ 3035.304704] Read of size 4 by task ksdioirqd/mmc2/1183
[ 3035.304744] CPU: 0 PID: 1183 Comm: ksdioirqd/mmc2 Tainted: G        W      3.18.0 #1169
[ 3035.304772] Call trace:
[ 3035.304825] [<ffffffc00020a520>] dump_backtrace+0x0/0x190
[ 3035.304864] [<ffffffc00020a6cc>] show_stack+0x1c/0x28
[ 3035.304901] [<ffffffc000b36db8>] dump_stack+0xa0/0xf8
[ 3035.304940] [<ffffffc00039c494>] kasan_report+0x120/0x4fc
[ 3035.304975] [<ffffffc00039b6b4>] __asan_load4+0x20/0x80
[ 3035.305546] [<ffffffbffc1f5aec>] mwifiex_check_next_scan_command+0x1a4/0x588 [mwifiex]
[ 3035.306091] [<ffffffbffc1f7aec>] mwifiex_handle_event_ext_scan_report+0x304/0x370 [mwifiex]
[ 3035.306735] [<ffffffbffc206bb8>] mwifiex_process_sta_event+0x6c0/0xf10 [mwifiex]
[ 3035.307200] [<ffffffbffc1e609c>] mwifiex_process_event+0x2f4/0x358 [mwifiex]
[ 3035.307612] [<ffffffbffc1e25c8>] mwifiex_main_process+0x3cc/0x80c [mwifiex]
[ 3035.307737] [<ffffffbffc2523a0>] mwifiex_sdio_interrupt+0x198/0x1c0 [mwifiex_sdio]
[ 3035.307785] [<ffffffc0008d9250>] process_sdio_pending_irqs+0x15c/0x1d4
[ 3035.307826] [<ffffffc0008d93f0>] sdio_irq_thread+0xd8/0x288
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 09e672a1
...@@ -3316,6 +3316,7 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, ...@@ -3316,6 +3316,7 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
struct mwifiex_private *sta_priv = struct mwifiex_private *sta_priv =
mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
sta_priv->scan_aborting = true;
for (i = 0; i < adapter->priv_num; i++) { for (i = 0; i < adapter->priv_num; i++) {
priv = adapter->priv[i]; priv = adapter->priv[i];
mwifiex_abort_cac(priv); mwifiex_abort_cac(priv);
...@@ -3344,19 +3345,21 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, ...@@ -3344,19 +3345,21 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
if (!wowlan) { if (!wowlan) {
mwifiex_dbg(adapter, ERROR, mwifiex_dbg(adapter, ERROR,
"None of the WOWLAN triggers enabled\n"); "None of the WOWLAN triggers enabled\n");
return 0; ret = 0;
goto done;
} }
if (!sta_priv->media_connected && !wowlan->nd_config) { if (!sta_priv->media_connected && !wowlan->nd_config) {
mwifiex_dbg(adapter, ERROR, mwifiex_dbg(adapter, ERROR,
"Can not configure WOWLAN in disconnected state\n"); "Can not configure WOWLAN in disconnected state\n");
return 0; ret = 0;
goto done;
} }
ret = mwifiex_set_mef_filter(sta_priv, wowlan); ret = mwifiex_set_mef_filter(sta_priv, wowlan);
if (ret) { if (ret) {
mwifiex_dbg(adapter, ERROR, "Failed to set MEF filter\n"); mwifiex_dbg(adapter, ERROR, "Failed to set MEF filter\n");
return ret; goto done;
} }
memset(&hs_cfg, 0, sizeof(hs_cfg)); memset(&hs_cfg, 0, sizeof(hs_cfg));
...@@ -3379,12 +3382,11 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, ...@@ -3379,12 +3382,11 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
hs_cfg.gap = adapter->hs_cfg.gap; hs_cfg.gap = adapter->hs_cfg.gap;
ret = mwifiex_set_hs_params(sta_priv, HostCmd_ACT_GEN_SET, ret = mwifiex_set_hs_params(sta_priv, HostCmd_ACT_GEN_SET,
MWIFIEX_SYNC_CMD, &hs_cfg); MWIFIEX_SYNC_CMD, &hs_cfg);
if (ret) { if (ret)
mwifiex_dbg(adapter, ERROR, mwifiex_dbg(adapter, ERROR, "Failed to set HS params\n");
"Failed to set HS params\n");
return ret;
}
done:
sta_priv->scan_aborting = false;
return ret; return ret;
} }
......
...@@ -1896,7 +1896,8 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv) ...@@ -1896,7 +1896,8 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
u8 id = 0; u8 id = 0;
struct mwifiex_user_scan_cfg *user_scan_cfg; struct mwifiex_user_scan_cfg *user_scan_cfg;
if (adapter->active_scan_triggered || !priv->scan_request) { if (adapter->active_scan_triggered || !priv->scan_request ||
priv->scan_aborting) {
adapter->active_scan_triggered = false; adapter->active_scan_triggered = false;
return 0; return 0;
} }
......
...@@ -708,7 +708,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) ...@@ -708,7 +708,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
case EVENT_EXT_SCAN_REPORT: case EVENT_EXT_SCAN_REPORT:
mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n"); mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
if (adapter->ext_scan) if (adapter->ext_scan && !priv->scan_aborting)
ret = mwifiex_handle_event_ext_scan_report(priv, ret = mwifiex_handle_event_ext_scan_report(priv,
adapter->event_skb->data); adapter->event_skb->data);
......
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