From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756167Ab1HCX2E (ORCPT ); Wed, 3 Aug 2011 19:28:04 -0400 Received: from cantor2.suse.de ([195.135.220.15]:33668 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756150Ab1HCX1n (ORCPT ); Wed, 3 Aug 2011 19:27:43 -0400 X-Mailbox-Line: From gregkh@clark.kroah.org Wed Aug 3 15:12:46 2011 Message-Id: <20110803221246.422803782@clark.kroah.org> User-Agent: quilt/0.48-16.4 Date: Wed, 03 Aug 2011 15:00:44 -0700 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: stable-review@kernel.org, torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Kalle Valo Subject: [024/102] ath6kl: fix crash when interface is closed but scan is ongoing In-Reply-To: <20110803221345.GA10346@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.0-stable review patch. If anyone has any objections, please let us know. ------------------ From: Kalle Valo commit 98ab5c7755b5cc9e1a8f2a57ccb22eac5e13ec50 upstream. When ath6kl module was resumed while a scan was ongoing, for example during suspend, the driver would crash in ar6k_cfg80211_scanComplete_event(): [26581.586440] Call Trace: [26581.586440] [] ? ar6k_cfg80211_scanComplete_event+0xaa/0xaa [ath6kl] [26581.586440] [] wmi_iterate_nodes+0xb/0xd [ath6kl] [26581.586440] [] ar6k_cfg80211_scanComplete_event+0x48/0xaa [ath6kl] [26581.586440] [] ar6000_close+0x77/0x7e [ath6kl] [26581.586440] [] __dev_close_many+0x87/0xab [26581.586440] [] dev_close_many+0x54/0xab [26581.586440] [] rollback_registered_many+0xa5/0x19e [26581.586440] [] rollback_registered+0x23/0x2f [26581.586440] [] unregister_netdevice_queue+0x4c/0x69 [26581.586440] [] unregister_netdev+0x18/0x1f [26581.586440] [] ar6000_destroy+0xf8/0x115 [ath6kl] [26581.586440] [] ar6k_cleanup_module+0x20/0x29 [ath6kl] [26581.586440] [] sys_delete_module+0x181/0x1d9 [26581.586440] [] ? lock_release_holdtime+0x2b/0xcd [26581.586440] [] ? sys_munmap+0x3b/0x42 [26581.586440] [] ? restore_all+0xf/0xf [26581.586440] [] sysenter_do_call+0x12/0x32 [26581.586440] Code: 89 53 6c 75 07 89 d8 e8 c0 ff ff ff 89 f0 e8 2c f2 a9 c7 5b 5e 5d c3 55 89 e5 57 56 53 89 c3 83 ec 08 89 55 f0 8d 78 04 89 4d ec <8b> b0 b8 00 00 00 46 89 b0 b8 00 00 00 89 f8 e8 ae ed a9 c7 8b Fix the function not to iterate nodes when the scan is aborted. The nodes are already freed when the module is being unloaded. Patch "ath6kl: Fix a kernel panic furing suspend/resume" tried to fix this already but it wasn't enough as a pointer was still used even after the null check. This patch removes the null check entirely as the wmi structure is not accessed anymore during module unload. Also fix a bug where the status was checked as a bitfield with '&' operator. But it's not a bitfield, just a regular (enum like) value. Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/cfg80211.c | 31 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -867,26 +867,31 @@ ar6k_cfg80211_scanComplete_event(struct AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status)); - if(ar->scan_request) - { - /* Translate data to cfg80211 mgmt format */ - if (ar->arWmi) - wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); + if (!ar->scan_request) + return; - cfg80211_scan_done(ar->scan_request, - ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false); + if ((status == A_ECANCELED) || (status == A_EBUSY)) { + cfg80211_scan_done(ar->scan_request, true); + goto out; + } + + /* Translate data to cfg80211 mgmt format */ + wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); - if(ar->scan_request->n_ssids && - ar->scan_request->ssids[0].ssid_len) { + cfg80211_scan_done(ar->scan_request, false); + + if(ar->scan_request->n_ssids && + ar->scan_request->ssids[0].ssid_len) { u8 i; for (i = 0; i < ar->scan_request->n_ssids; i++) { - wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, - 0, NULL); + wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, + 0, NULL); } - } - ar->scan_request = NULL; } + +out: + ar->scan_request = NULL; } static int