aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/scan.c
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2014-05-28 00:39:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-05-29 13:10:35 -0400
commit214450498380c210a2ab98f884f4ba72998eba15 (patch)
treeb0ea4ddf092d904c7724f47cc300a7d2b48434ea /drivers/net/wireless/mwifiex/scan.c
parent6fe551434c0844fb82785086bdbac312744a22d2 (diff)
mwifiex: fix a crash in extended scan event processing
[113.967694] Unable to handle kernel NULL pointer dereference at virtual address 00000020 ............ [113.967859] PC is at mwifiex_update_rxreor_flags+0xfc/0x430 ............ [113.968110] mwifiex_update_rxreor_flags+0xfc/0x430 [113.968129] mwifiex_handle_event_ext_scan_report+0x1e4/0x21c [113.968148] mwifiex_process_sta_event+0x410/0x508 [113.968165] mwifiex_process_event+0x184/0x1e0 [113.968181] mwifiex_main_process+0x220/0x48c [113.968197] mwifiex_sdio_interrupt+0xc8/0x1cc [113.968210] sdio_irq_thread+0x11c/0x290 In case of legacy scan, adapter->curr_cmd is guranteed to be non-NULL in check_next_scan_cmd. This may not be case in extended scan where scan command response would come earlier and set curr_cmd to NULL. Extended scan event comes later and while trying to complete IOCTL for scan, driver would crash in dereferencing adapter->curr_cmd->wait_q_enabled. Avoid this by completing IOCTL in case of legacy scans only. Internal scan would be completed while handling extended scan command response. Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/scan.c')
-rw-r--r--drivers/net/wireless/mwifiex/scan.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index d75f4ebd4bdc..45c5b3450cf5 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1738,6 +1738,19 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1738 return 0; 1738 return 0;
1739} 1739}
1740 1740
1741static void mwifiex_complete_scan(struct mwifiex_private *priv)
1742{
1743 struct mwifiex_adapter *adapter = priv->adapter;
1744
1745 if (adapter->curr_cmd->wait_q_enabled) {
1746 adapter->cmd_wait_q.status = 0;
1747 if (!priv->scan_request) {
1748 dev_dbg(adapter->dev, "complete internal scan\n");
1749 mwifiex_complete_cmd(adapter, adapter->curr_cmd);
1750 }
1751 }
1752}
1753
1741static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) 1754static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1742{ 1755{
1743 struct mwifiex_adapter *adapter = priv->adapter; 1756 struct mwifiex_adapter *adapter = priv->adapter;
@@ -1751,16 +1764,9 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1751 adapter->scan_processing = false; 1764 adapter->scan_processing = false;
1752 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 1765 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1753 1766
1754 /* Need to indicate IOCTL complete */ 1767 if (!adapter->ext_scan)
1755 if (adapter->curr_cmd->wait_q_enabled) { 1768 mwifiex_complete_scan(priv);
1756 adapter->cmd_wait_q.status = 0; 1769
1757 if (!priv->scan_request) {
1758 dev_dbg(adapter->dev,
1759 "complete internal scan\n");
1760 mwifiex_complete_cmd(adapter,
1761 adapter->curr_cmd);
1762 }
1763 }
1764 if (priv->report_scan_result) 1770 if (priv->report_scan_result)
1765 priv->report_scan_result = false; 1771 priv->report_scan_result = false;
1766 1772
@@ -1965,6 +1971,9 @@ int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1965int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) 1971int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
1966{ 1972{
1967 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n"); 1973 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");
1974
1975 mwifiex_complete_scan(priv);
1976
1968 return 0; 1977 return 0;
1969} 1978}
1970 1979