public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Jouni Malinen <jouni@codeaurora.org>,
	Johannes Berg <johannes.berg@intel.com>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH AUTOSEL 4.4 05/25] cfg80211: Address some corner cases in scan result channel updating
Date: Tue, 16 Oct 2018 00:15:46 -0400	[thread overview]
Message-ID: <20181016041606.135876-5-sashal@kernel.org> (raw)
In-Reply-To: <20181016041606.135876-1-sashal@kernel.org>

From: Jouni Malinen <jouni@codeaurora.org>

[ Upstream commit 119f94a6fefcc76d47075b83d2b73d04c895df78 ]

cfg80211_get_bss_channel() is used to update the RX channel based on the
available frame payload information (channel number from DSSS Parameter
Set element or HT Operation element). This is needed on 2.4 GHz channels
where frames may be received on neighboring channels due to overlapping
frequency range.

This might of some use on the 5 GHz band in some corner cases, but
things are more complex there since there is no n:1 or 1:n mapping
between channel numbers and frequencies due to multiple different
starting frequencies in different operating classes. This could result
in ieee80211_channel_to_frequency() returning incorrect frequency and
ieee80211_get_channel() returning incorrect channel information (or
indication of no match). In the previous implementation, this could
result in some scan results being dropped completely, e.g., for the 4.9
GHz channels. That prevented connection to such BSSs.

Fix this by using the driver-provided channel pointer if
ieee80211_get_channel() does not find matching channel data for the
channel number in the frame payload and if the scan is done with 5 MHz
or 10 MHz channel bandwidth. While doing this, also add comments
describing what the function is trying to achieve to make it easier to
understand what happens here and why.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/wireless/scan.c | 58 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 8dde12a11725..00219f386283 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -974,13 +974,23 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
 	return NULL;
 }
 
+/*
+ * Update RX channel information based on the available frame payload
+ * information. This is mainly for the 2.4 GHz band where frames can be received
+ * from neighboring channels and the Beacon frames use the DSSS Parameter Set
+ * element to indicate the current (transmitting) channel, but this might also
+ * be needed on other bands if RX frequency does not match with the actual
+ * operating channel of a BSS.
+ */
 static struct ieee80211_channel *
 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
-			 struct ieee80211_channel *channel)
+			 struct ieee80211_channel *channel,
+			 enum nl80211_bss_scan_width scan_width)
 {
 	const u8 *tmp;
 	u32 freq;
 	int channel_number = -1;
+	struct ieee80211_channel *alt_channel;
 
 	tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
 	if (tmp && tmp[1] == 1) {
@@ -994,16 +1004,45 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
 		}
 	}
 
-	if (channel_number < 0)
+	if (channel_number < 0) {
+		/* No channel information in frame payload */
 		return channel;
+	}
 
 	freq = ieee80211_channel_to_frequency(channel_number, channel->band);
-	channel = ieee80211_get_channel(wiphy, freq);
-	if (!channel)
-		return NULL;
-	if (channel->flags & IEEE80211_CHAN_DISABLED)
+	alt_channel = ieee80211_get_channel(wiphy, freq);
+	if (!alt_channel) {
+		if (channel->band == NL80211_BAND_2GHZ) {
+			/*
+			 * Better not allow unexpected channels when that could
+			 * be going beyond the 1-11 range (e.g., discovering
+			 * BSS on channel 12 when radio is configured for
+			 * channel 11.
+			 */
+			return NULL;
+		}
+
+		/* No match for the payload channel number - ignore it */
+		return channel;
+	}
+
+	if (scan_width == NL80211_BSS_CHAN_WIDTH_10 ||
+	    scan_width == NL80211_BSS_CHAN_WIDTH_5) {
+		/*
+		 * Ignore channel number in 5 and 10 MHz channels where there
+		 * may not be an n:1 or 1:n mapping between frequencies and
+		 * channel numbers.
+		 */
+		return channel;
+	}
+
+	/*
+	 * Use the channel determined through the payload channel number
+	 * instead of the RX channel reported by the driver.
+	 */
+	if (alt_channel->flags & IEEE80211_CHAN_DISABLED)
 		return NULL;
-	return channel;
+	return alt_channel;
 }
 
 /* Returned bss is reference counted and must be cleaned up appropriately. */
@@ -1028,7 +1067,8 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
 		    (data->signal < 0 || data->signal > 100)))
 		return NULL;
 
-	channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan);
+	channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan,
+					   data->scan_width);
 	if (!channel)
 		return NULL;
 
@@ -1126,7 +1166,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
 		return NULL;
 
 	channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
-					   ielen, data->chan);
+					   ielen, data->chan, data->scan_width);
 	if (!channel)
 		return NULL;
 
-- 
2.17.1

  parent reply	other threads:[~2018-10-16  4:15 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-16  4:15 [PATCH AUTOSEL 4.4 01/25] xfrm: Validate address prefix lengths in the xfrm selector Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 02/25] xfrm6: call kfree_skb when skb is toobig Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 03/25] mac80211: Always report TX status Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 04/25] cfg80211: reg: Init wiphy_idx in regulatory_hint_core() Sasha Levin
2018-10-16  4:15 ` Sasha Levin [this message]
2018-11-02  9:19   ` [PATCH AUTOSEL 4.4 05/25] cfg80211: Address some corner cases in scan result channel updating Greg KH
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 06/25] ARM: 8799/1: mm: fix pci_ioremap_io() offset check Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 07/25] xfrm: validate template mode Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 08/25] mac80211_hwsim: do not omit multicast announce of first added radio Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 09/25] Bluetooth: SMP: fix crash in unpairing Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 10/25] pxa168fb: prepare the clock Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 11/25] bonding: avoid possible dead-lock Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 12/25] bnxt_en: Fix TX timeout during netpoll Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 13/25] asix: Check for supported Wake-on-LAN modes Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 14/25] ax88179_178a: " Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 15/25] lan78xx: " Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 16/25] sr9800: " Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 17/25] r8152: Check for supported Wake-on-LAN Modes Sasha Levin
2018-10-16  4:15 ` [PATCH AUTOSEL 4.4 18/25] smsc75xx: Check for Wake-on-LAN modes Sasha Levin
2018-10-16  4:16 ` [PATCH AUTOSEL 4.4 19/25] smsc95xx: " Sasha Levin
2018-10-16  4:16 ` [PATCH AUTOSEL 4.4 20/25] qlcnic: fix Tx descriptor corruption on 82xx devices Sasha Levin
2018-10-16  4:16 ` [PATCH AUTOSEL 4.4 21/25] i2c: i2c-scmi: fix for i2c_smbus_write_block_data Sasha Levin
2018-10-16  4:16 ` [PATCH AUTOSEL 4.4 22/25] perf/ring_buffer: Prevent concurent ring buffer access Sasha Levin
2018-10-16  4:16 ` [PATCH AUTOSEL 4.4 23/25] net/usb: cancel pending work when unbinding smsc75xx Sasha Levin
2018-10-16  4:16 ` [PATCH AUTOSEL 4.4 24/25] net: cxgb3_main: fix a missing-check bug Sasha Levin
2018-10-16  4:16 ` [PATCH AUTOSEL 4.4 25/25] mm/vmstat.c: fix outdated vmstat_text Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181016041606.135876-5-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=johannes.berg@intel.com \
    --cc=jouni@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox