summaryrefslogtreecommitdiff
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
authorBenjamin Berg <benjamin.berg@intel.com>2023-06-18 21:49:52 +0300
committerJohannes Berg <johannes.berg@intel.com>2023-06-19 12:05:30 +0200
commitdc92e54c30c4bc9d30e674a445dfe1afdca991cf (patch)
treede1c8ff6e09e673f01bdebda4d6a73f29011372c /net/wireless/scan.c
parent50181fe4f59dcfae391523def6f62e32d86c46b1 (diff)
wifi: cfg80211: use structs for TBTT information access
Make the data access a bit nicer overall by using structs. There is a small change here to also accept a TBTT information length of eight bytes as we do not require the 20 MHz PSD information. This also fixes a bug reading the short SSID on big endian machines. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230618214436.4c3f8901c1bc.Ic3e94fd6e1bccff7948a252ad3bb87e322690a17@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 974a6a8240dd..f0b4d7671d17 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -574,39 +574,41 @@ static void cfg80211_free_coloc_ap_list(struct list_head *coloc_ap_list)
static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
const u8 *pos, u8 length,
const struct element *ssid_elem,
- int s_ssid_tmp)
+ u32 s_ssid_tmp)
{
- /* skip the TBTT offset */
- pos++;
+ u8 bss_params;
- /* ignore entries with invalid BSSID */
- if (!is_valid_ether_addr(pos))
- return -EINVAL;
-
- memcpy(entry->bssid, pos, ETH_ALEN);
- pos += ETH_ALEN;
+ /* The length is already verified by the caller to contain bss_params */
+ if (length > sizeof(struct ieee80211_tbtt_info_7_8_9)) {
+ struct ieee80211_tbtt_info_ge_11 *tbtt_info = (void *)pos;
- if (length >= IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM) {
- memcpy(&entry->short_ssid, pos,
- sizeof(entry->short_ssid));
+ memcpy(entry->bssid, tbtt_info->bssid, ETH_ALEN);
+ entry->short_ssid = le32_to_cpu(tbtt_info->short_ssid);
entry->short_ssid_valid = true;
- pos += 4;
+
+ bss_params = tbtt_info->bss_params;
+ } else {
+ struct ieee80211_tbtt_info_7_8_9 *tbtt_info = (void *)pos;
+
+ memcpy(entry->bssid, tbtt_info->bssid, ETH_ALEN);
+
+ bss_params = tbtt_info->bss_params;
}
+ /* ignore entries with invalid BSSID */
+ if (!is_valid_ether_addr(entry->bssid))
+ return -EINVAL;
+
/* skip non colocated APs */
- if (!cfg80211_parse_bss_param(*pos, entry))
+ if (!cfg80211_parse_bss_param(bss_params, entry))
return -EINVAL;
- pos++;
- if (length == IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM) {
- /*
- * no information about the short ssid. Consider the entry valid
- * for now. It would later be dropped in case there are explicit
- * SSIDs that need to be matched
- */
- if (!entry->same_ssid)
- return 0;
- }
+ /* no information about the short ssid. Consider the entry valid
+ * for now. It would later be dropped in case there are explicit
+ * SSIDs that need to be matched
+ */
+ if (!entry->same_ssid && !entry->short_ssid_valid)
+ return 0;
if (entry->same_ssid) {
entry->short_ssid = s_ssid_tmp;
@@ -617,10 +619,10 @@ static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
* cfg80211_parse_colocated_ap(), before calling this
* function.
*/
- memcpy(&entry->ssid, &ssid_elem->data,
- ssid_elem->datalen);
+ memcpy(&entry->ssid, &ssid_elem->data, ssid_elem->datalen);
entry->ssid_len = ssid_elem->datalen;
}
+
return 0;
}
@@ -682,8 +684,11 @@ static int cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies,
* next AP info
*/
if (band != NL80211_BAND_6GHZ ||
- (length != IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM &&
- length < IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM)) {
+ !(length == offsetofend(struct ieee80211_tbtt_info_7_8_9,
+ bss_params) ||
+ length == sizeof(struct ieee80211_tbtt_info_7_8_9) ||
+ length >= offsetofend(struct ieee80211_tbtt_info_ge_11,
+ bss_params))) {
pos += count * length;
continue;
}