diff options
-rw-r--r-- | include/net/cfg80211.h | 4 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 26 |
2 files changed, 28 insertions, 2 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6bc161d653f3..140354f5f15b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1296,6 +1296,8 @@ struct cfg80211_unsol_bcast_probe_resp { * @ht_cap: HT capabilities (or %NULL if HT isn't enabled) * @vht_cap: VHT capabilities (or %NULL if VHT isn't enabled) * @he_cap: HE capabilities (or %NULL if HE isn't enabled) + * @eht_cap: EHT capabilities (or %NULL if EHT isn't enabled) + * @eht_oper: EHT operation IE (or %NULL if EHT isn't enabled) * @ht_required: stations must support HT * @vht_required: stations must support VHT * @twt_responder: Enable Target Wait Time @@ -1332,6 +1334,8 @@ struct cfg80211_ap_settings { const struct ieee80211_vht_cap *vht_cap; const struct ieee80211_he_cap_elem *he_cap; const struct ieee80211_he_operation *he_oper; + const struct ieee80211_eht_cap_elem *eht_cap; + const struct ieee80211_eht_operation *eht_oper; bool ht_required, vht_required, he_required, sae_h2e_required; bool twt_responder; u32 flags; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e2b6740268a6..eda2ad029c90 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5522,7 +5522,7 @@ static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params, * HT/VHT requirements/capabilities, we parse them out of the IEs for the * benefit of drivers that rebuild IEs in the firmware. */ -static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params) +static int nl80211_calculate_ap_params(struct cfg80211_ap_settings *params) { const struct cfg80211_beacon_data *bcn = ¶ms->beacon; size_t ies_len = bcn->tail_len; @@ -5548,6 +5548,26 @@ static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params) cap = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ies, ies_len); if (cap && cap->datalen >= sizeof(*params->he_oper) + 1) params->he_oper = (void *)(cap->data + 1); + cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_CAPABILITY, ies, ies_len); + if (cap) { + if (!cap->datalen) + return -EINVAL; + 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)) + return -EINVAL; + } + cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_OPERATION, ies, ies_len); + if (cap) { + if (!cap->datalen) + return -EINVAL; + params->eht_oper = (void *)(cap->data + 1); + if (!ieee80211_eht_oper_size_ok((const u8 *)params->eht_oper, + cap->datalen - 1)) + return -EINVAL; + } + return 0; } static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, @@ -5873,7 +5893,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) goto out_unlock; } - nl80211_calculate_ap_params(params); + err = nl80211_calculate_ap_params(params); + if (err) + goto out_unlock; if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]) params->flags = nla_get_u32( |