wifi: cfg80211/mac80211: check EHT capability size correctly
authorJohannes Berg <johannes.berg@intel.com>
Tue, 16 Aug 2022 09:26:23 +0000 (11:26 +0200)
committerChristian Lamparter <chunkeey@gmail.com>
Sun, 21 May 2023 21:03:28 +0000 (23:03 +0200)
For AP/non-AP the EHT MCS/NSS subfield size differs, the
4-octet subfield is only used for 20 MHz-only non-AP STA.
Pass an argument around everywhere to be able to parse it
properly.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
include/linux/ieee80211.h

index 26b2dce698ca0ce437205957c24f3147810678d7..874cfde3e2c9b525640ab627e3d510ce4a1c16b1 100644 (file)
@@ -2904,7 +2904,8 @@ ieee80211_he_spr_size(const u8 *he_spr_ie)
 /* Calculate 802.11be EHT capabilities IE Tx/Rx EHT MCS NSS Support Field size */
 static inline u8
 ieee80211_eht_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap,
-                          const struct ieee80211_eht_cap_elem_fixed *eht_cap)
+                          const struct ieee80211_eht_cap_elem_fixed *eht_cap,
+                          bool from_ap)
 {
        u8 count = 0;
 
@@ -2925,7 +2926,10 @@ ieee80211_eht_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap,
        if (eht_cap->phy_cap_info[0] & IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ)
                count += 3;
 
-       return count ? count : 4;
+       if (count)
+               return count;
+
+       return from_ap ? 3 : 4;
 }
 
 /* 802.11be EHT PPE Thresholds */
@@ -2961,7 +2965,8 @@ ieee80211_eht_ppe_size(u16 ppe_thres_hdr, const u8 *phy_cap_info)
 }
 
 static inline bool
-ieee80211_eht_capa_size_ok(const u8 *he_capa, const u8 *data, u8 len)
+ieee80211_eht_capa_size_ok(const u8 *he_capa, const u8 *data, u8 len,
+                          bool from_ap)
 {
        const struct ieee80211_eht_cap_elem_fixed *elem = (const void *)data;
        u8 needed = sizeof(struct ieee80211_eht_cap_elem_fixed);
@@ -2970,7 +2975,8 @@ ieee80211_eht_capa_size_ok(const u8 *he_capa, const u8 *data, u8 len)
                return false;
 
        needed += ieee80211_eht_mcs_nss_size((const void *)he_capa,
-                                            (const void *)data);
+                                            (const void *)data,
+                                            from_ap);
        if (len < needed)
                return false;