Simplify VHT Capabilities element parsing
Check the element length in the parser and remove the length field from
struct ieee802_11_elems since the element is of fixed length.
Signed-off-by: Jouni Malinen <j@w1.fi>
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 1299677..5b26558 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1295,8 +1295,7 @@
#endif /* CONFIG_IEEE80211N */
#ifdef CONFIG_IEEE80211AC
- resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities,
- elems.vht_capabilities_len);
+ resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index a097235..44c1bff 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -70,7 +70,7 @@
void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta);
void ht40_intolerant_remove(struct hostapd_iface *iface, struct sta_info *sta);
u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
- const u8 *vht_capab, size_t vht_capab_len);
+ const u8 *vht_capab);
u16 set_sta_vht_opmode(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *vht_opmode);
void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 171538a..5bf1b5d 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -132,11 +132,10 @@
u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
- const u8 *vht_capab, size_t vht_capab_len)
+ const u8 *vht_capab)
{
/* Disable VHT caps for STAs associated to no-VHT BSSes. */
if (!vht_capab ||
- vht_capab_len < sizeof(struct ieee80211_vht_capabilities) ||
hapd->conf->disable_11ac ||
!check_valid_vht_mcs(hapd->iface->current_mode, vht_capab)) {
sta->flags &= ~WLAN_STA_VHT;
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 3866ddf..922dea0 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -286,8 +286,9 @@
elems->peer_mgmt_len = elen;
break;
case WLAN_EID_VHT_CAP:
+ if (elen < sizeof(struct ieee80211_vht_capabilities))
+ break;
elems->vht_capabilities = pos;
- elems->vht_capabilities_len = elen;
break;
case WLAN_EID_VHT_OPERATION:
elems->vht_operation = pos;
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 5306783..24e558e 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -65,7 +65,6 @@
u8 mesh_config_len;
u8 mesh_id_len;
u8 peer_mgmt_len;
- u8 vht_capabilities_len;
u8 vht_operation_len;
u8 vendor_ht_cap_len;
u8 vendor_vht_len;
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 490fcaa..6b1df71 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -1603,9 +1603,7 @@
static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde,
struct wpa_tdls_peer *peer)
{
- if (!kde->vht_capabilities ||
- kde->vht_capabilities_len <
- sizeof(struct ieee80211_vht_capabilities) ) {
+ if (!kde->vht_capabilities) {
wpa_printf(MSG_DEBUG, "TDLS: No supported vht capabilities "
"received");
return 0;
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index ec3eab0..0c37b35 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -559,9 +559,10 @@
} else if (*pos == WLAN_EID_VHT_AID) {
if (pos[1] >= 2)
ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
- } else if (*pos == WLAN_EID_VHT_CAP) {
+ } else if (*pos == WLAN_EID_VHT_CAP &&
+ pos[1] >= sizeof(struct ieee80211_vht_capabilities))
+ {
ie->vht_capabilities = pos + 2;
- ie->vht_capabilities_len = pos[1];
} else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
ie->qosinfo = pos[2];
} else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
diff --git a/src/rsn_supp/wpa_ie.h b/src/rsn_supp/wpa_ie.h
index edabfc7..fe95af0 100644
--- a/src/rsn_supp/wpa_ie.h
+++ b/src/rsn_supp/wpa_ie.h
@@ -51,7 +51,6 @@
size_t ext_supp_rates_len;
const u8 *ht_capabilities;
const u8 *vht_capabilities;
- size_t vht_capabilities_len;
const u8 *supp_channels;
size_t supp_channels_len;
const u8 *supp_oper_classes;