summaryrefslogtreecommitdiff
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2022-08-16 12:26:23 +0300
committerJohannes Berg <johannes.berg@intel.com>2022-08-25 11:41:24 +0300
commitea5cba269fb1fe22b84f4d01bb3d56320e6ffa3e (patch)
tree3d904375046604957f92b627e15a4d90ff904f29 /net/wireless/nl80211.c
parent4992b36041f4263a9df8ee64259d2da6f6e4444a (diff)
downloadlinux-ea5cba269fb1fe22b84f4d01bb3d56320e6ffa3e.tar.xz
wifi: cfg80211/mac80211: check EHT capability size correctly
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>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 72242681ab86..8568304f96af 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1820,10 +1820,15 @@ nl80211_send_iftype_data(struct sk_buff *msg,
if (eht_cap->has_eht && he_cap->has_he) {
u8 mcs_nss_size, ppe_thresh_size;
u16 ppe_thres_hdr;
+ bool is_ap;
+
+ is_ap = iftdata->types_mask & BIT(NL80211_IFTYPE_AP) ||
+ iftdata->types_mask & BIT(NL80211_IFTYPE_P2P_GO);
mcs_nss_size =
ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem,
- &eht_cap->eht_cap_elem);
+ &eht_cap->eht_cap_elem,
+ is_ap);
ppe_thres_hdr = get_unaligned_le16(&eht_cap->eht_ppe_thres[0]);
ppe_thresh_size =
@@ -5668,7 +5673,7 @@ static int nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
params->eht_cap = (void *)(cap->data + 1);
if (!ieee80211_eht_capa_size_ok((const u8 *)params->he_cap,
(const u8 *)params->eht_cap,
- cap->datalen - 1))
+ cap->datalen - 1, true))
return -EINVAL;
}
cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_OPERATION, ies, ies_len);
@@ -6897,7 +6902,8 @@ static int nl80211_set_station_tdls(struct genl_info *info,
if (!ieee80211_eht_capa_size_ok((const u8 *)params->link_sta_params.he_capa,
(const u8 *)params->link_sta_params.eht_capa,
- params->link_sta_params.eht_capa_len))
+ params->link_sta_params.eht_capa_len,
+ false))
return -EINVAL;
}
}
@@ -7208,7 +7214,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (!ieee80211_eht_capa_size_ok((const u8 *)params.link_sta_params.he_capa,
(const u8 *)params.link_sta_params.eht_capa,
- params.link_sta_params.eht_capa_len))
+ params.link_sta_params.eht_capa_len,
+ false))
return -EINVAL;
}
}
@@ -15968,7 +15975,8 @@ nl80211_add_mod_link_station(struct sk_buff *skb, struct genl_info *info,
if (!ieee80211_eht_capa_size_ok((const u8 *)params.he_capa,
(const u8 *)params.eht_capa,
- params.eht_capa_len))
+ params.eht_capa_len,
+ false))
return -EINVAL;
}
}