Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c80c39d authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

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 1b9ca027
Loading
Loading
Loading
Loading
+16 −14
Original line number Diff line number Diff line
@@ -405,31 +405,33 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,

	mutex_lock(&priv->mutex);

	if (test_bit(STATUS_SCANNING, &priv->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->mutex);

	return ret;