diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-09-23 02:14:54 +0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-27 22:34:07 +0400 |
commit | 8bd2c1ead5e2b67270aedfc95dcac8d6955db4e5 (patch) | |
tree | b31915ea6ed5c70d79e3f94dd60603152c44fbc1 | |
parent | 7f90dce1ea9de432cf1f196c743a8d5a119e38ba (diff) | |
download | linux-8bd2c1ead5e2b67270aedfc95dcac8d6955db4e5.tar.xz |
iwlagn: fix dangling scan request
If iwl_scan_initiate() fails for any reason,
priv->scan_request and priv->scan_vif are left
dangling. This can lead to a crash later when
iwl_bg_scan_completed() tries to run a pending
scan request.
In practice, this seems to be very rare due to
the STATUS_SCANNING check earlier. That check,
however, is wrong -- it should allow a scan to
be queued when a reset/roc scan is going on.
When a normal scan is already going on, a new
one can't be issued by mac80211, so that code
can be removed completely. I introduced this
bug when adding off-channel support in commit
266af4c745952e9bebf687dd68af58df553cb59d.
Cc: stable@kernel.org [3.0]
Reported-by: Peng Yan <peng.yan@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 07af6ec8d9d2..74204ec5b267 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -874,31 +874,33 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, mutex_lock(&priv->shrd->mutex); - if (test_bit(STATUS_SCANNING, &priv->shrd->status) && - priv->scan_type != IWL_SCAN_NORMAL) { - IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); - ret = -EAGAIN; - goto out_unlock; - } - - /* mac80211 will only ask for one band at a time */ - priv->scan_request = req; - priv->scan_vif = vif; - /* * If an internal scan is in progress, just set * up the scan_request as per above. */ if (priv->scan_type != IWL_SCAN_NORMAL) { - IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); + IWL_DEBUG_SCAN(priv, + "SCAN request during internal scan - defer\n"); + priv->scan_request = req; + priv->scan_vif = vif; ret = 0; - } else + } else { + priv->scan_request = req; + priv->scan_vif = vif; + /* + * mac80211 will only ask for one band at a time + * so using channels[0] here is ok + */ ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL, req->channels[0]->band); + if (ret) { + priv->scan_request = NULL; + priv->scan_vif = NULL; + } + } IWL_DEBUG_MAC80211(priv, "leave\n"); -out_unlock: mutex_unlock(&priv->shrd->mutex); return ret; |