From 16d25da94f3d6542a0bbd25a85d247c970026f8a Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 27 Jun 2016 14:16:29 +0530 Subject: [PATCH] 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] [] dump_backtrace+0x0/0x190 [ 3035.304864] [] show_stack+0x1c/0x28 [ 3035.304901] [] dump_stack+0xa0/0xf8 [ 3035.304940] [] kasan_report+0x120/0x4fc [ 3035.304975] [] __asan_load4+0x20/0x80 [ 3035.305546] [] mwifiex_check_next_scan_command+0x1a4/0x588 [mwifiex] [ 3035.306091] [] mwifiex_handle_event_ext_scan_report+0x304/0x370 [mwifiex] [ 3035.306735] [] mwifiex_process_sta_event+0x6c0/0xf10 [mwifiex] [ 3035.307200] [] mwifiex_process_event+0x2f4/0x358 [mwifiex] [ 3035.307612] [] mwifiex_main_process+0x3cc/0x80c [mwifiex] [ 3035.307737] [] mwifiex_sdio_interrupt+0x198/0x1c0 [mwifiex_sdio] [ 3035.307785] [] process_sdio_pending_irqs+0x15c/0x1d4 [ 3035.307826] [] sdio_irq_thread+0xd8/0x288 Signed-off-by: Amitkumar Karwar Signed-off-by: Kalle Valo --- .../net/wireless/marvell/mwifiex/cfg80211.c | 18 ++++++++++-------- drivers/net/wireless/marvell/mwifiex/scan.c | 3 ++- .../net/wireless/marvell/mwifiex/sta_event.c | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index e651455ee829..e6befd58cbd5 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -3316,6 +3316,7 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, struct mwifiex_private *sta_priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); + sta_priv->scan_aborting = true; for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; mwifiex_abort_cac(priv); @@ -3344,19 +3345,21 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, if (!wowlan) { mwifiex_dbg(adapter, ERROR, "None of the WOWLAN triggers enabled\n"); - return 0; + ret = 0; + goto done; } if (!sta_priv->media_connected && !wowlan->nd_config) { mwifiex_dbg(adapter, ERROR, "Can not configure WOWLAN in disconnected state\n"); - return 0; + ret = 0; + goto done; } ret = mwifiex_set_mef_filter(sta_priv, wowlan); if (ret) { mwifiex_dbg(adapter, ERROR, "Failed to set MEF filter\n"); - return ret; + goto done; } memset(&hs_cfg, 0, sizeof(hs_cfg)); @@ -3379,12 +3382,11 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, hs_cfg.gap = adapter->hs_cfg.gap; ret = mwifiex_set_hs_params(sta_priv, HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, &hs_cfg); - if (ret) { - mwifiex_dbg(adapter, ERROR, - "Failed to set HS params\n"); - return ret; - } + if (ret) + mwifiex_dbg(adapter, ERROR, "Failed to set HS params\n"); +done: + sta_priv->scan_aborting = false; return ret; } diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index 96d0d8652678..87e700009fd0 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -1896,7 +1896,8 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv) u8 id = 0; 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; return 0; } diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c index 0cefd40b2762..7c01778b6bb5 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -708,7 +708,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_EXT_SCAN_REPORT: 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, adapter->event_skb->data); -- 2.20.1