Commit 8bd2c1ea authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

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
266af4c7.

Cc: stable@kernel.org [3.0]
Reported-by: default avatarPeng Yan <peng.yan@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7f90dce1
...@@ -874,31 +874,33 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, ...@@ -874,31 +874,33 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
mutex_lock(&priv->shrd->mutex); 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 * If an internal scan is in progress, just set
* up the scan_request as per above. * up the scan_request as per above.
*/ */
if (priv->scan_type != IWL_SCAN_NORMAL) { 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; 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, ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL,
req->channels[0]->band); req->channels[0]->band);
if (ret) {
priv->scan_request = NULL;
priv->scan_vif = NULL;
}
}
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
out_unlock:
mutex_unlock(&priv->shrd->mutex); mutex_unlock(&priv->shrd->mutex);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment