diff options
author | Avinash Patil <patila@marvell.com> | 2014-05-28 00:39:32 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-29 13:10:35 -0400 |
commit | 214450498380c210a2ab98f884f4ba72998eba15 (patch) | |
tree | b0ea4ddf092d904c7724f47cc300a7d2b48434ea /drivers/net/wireless/mwifiex/scan.c | |
parent | 6fe551434c0844fb82785086bdbac312744a22d2 (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.c | 29 |
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 | ||
1741 | static 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 | |||
1741 | static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) | 1754 | static 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, | |||
1965 | int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) | 1971 | int 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 | ||