mwifiex: Don't abort on small, spec-compliant vendor IEs
commit 63d7ef36103d26f20325a921ecc96a3288560146 upstream. Per the 802.11 specification, vendor IEs are (at minimum) only required to contain an OUI. A type field is also included in ieee80211.h (struct ieee80211_vendor_ie) but doesn't appear in the specification. The remaining fields (subtype, version) are a convention used in WMM headers. Thus, we should not reject vendor-specific IEs that have only the minimum length (3 bytes) -- we should skip over them (since we only want to match longer IEs, that match either WMM or WPA formats). We can reject elements that don't have the minimum-required 3 byte OUI. While we're at it, move the non-standard subtype and version fields into the WMM structs, to avoid this confusion in the future about generic "vendor header" attributes. Fixes: 685c9b7750bf ("mwifiex: Abort at too short BSS descriptor element") Cc: Takashi Iwai <tiwai@suse.de> Signed-off-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e722fb795f
commit
052020f72a
@ -1719,9 +1719,10 @@ struct mwifiex_ie_types_wmm_queue_status {
|
||||
struct ieee_types_vendor_header {
|
||||
u8 element_id;
|
||||
u8 len;
|
||||
u8 oui[4]; /* 0~2: oui, 3: oui_type */
|
||||
u8 oui_subtype;
|
||||
u8 version;
|
||||
struct {
|
||||
u8 oui[3];
|
||||
u8 oui_type;
|
||||
} __packed oui;
|
||||
} __packed;
|
||||
|
||||
struct ieee_types_wmm_parameter {
|
||||
@ -1735,6 +1736,9 @@ struct ieee_types_wmm_parameter {
|
||||
* Version [1]
|
||||
*/
|
||||
struct ieee_types_vendor_header vend_hdr;
|
||||
u8 oui_subtype;
|
||||
u8 version;
|
||||
|
||||
u8 qos_info_bitmap;
|
||||
u8 reserved;
|
||||
struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS];
|
||||
@ -1752,6 +1756,8 @@ struct ieee_types_wmm_info {
|
||||
* Version [1]
|
||||
*/
|
||||
struct ieee_types_vendor_header vend_hdr;
|
||||
u8 oui_subtype;
|
||||
u8 version;
|
||||
|
||||
u8 qos_info_bitmap;
|
||||
} __packed;
|
||||
|
@ -1349,21 +1349,25 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||
break;
|
||||
|
||||
case WLAN_EID_VENDOR_SPECIFIC:
|
||||
if (element_len + 2 < sizeof(vendor_ie->vend_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
vendor_ie = (struct ieee_types_vendor_specific *)
|
||||
current_ptr;
|
||||
|
||||
if (!memcmp
|
||||
(vendor_ie->vend_hdr.oui, wpa_oui,
|
||||
sizeof(wpa_oui))) {
|
||||
/* 802.11 requires at least 3-byte OUI. */
|
||||
if (element_len < sizeof(vendor_ie->vend_hdr.oui.oui))
|
||||
return -EINVAL;
|
||||
|
||||
/* Not long enough for a match? Skip it. */
|
||||
if (element_len < sizeof(wpa_oui))
|
||||
break;
|
||||
|
||||
if (!memcmp(&vendor_ie->vend_hdr.oui, wpa_oui,
|
||||
sizeof(wpa_oui))) {
|
||||
bss_entry->bcn_wpa_ie =
|
||||
(struct ieee_types_vendor_specific *)
|
||||
current_ptr;
|
||||
bss_entry->wpa_offset = (u16)
|
||||
(current_ptr - bss_entry->beacon_buf);
|
||||
} else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
|
||||
} else if (!memcmp(&vendor_ie->vend_hdr.oui, wmm_oui,
|
||||
sizeof(wmm_oui))) {
|
||||
if (total_ie_len ==
|
||||
sizeof(struct ieee_types_wmm_parameter) ||
|
||||
|
@ -1374,7 +1374,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
|
||||
/* Test to see if it is a WPA IE, if not, then it is a
|
||||
* gen IE
|
||||
*/
|
||||
if (!memcmp(pvendor_ie->oui, wpa_oui,
|
||||
if (!memcmp(&pvendor_ie->oui, wpa_oui,
|
||||
sizeof(wpa_oui))) {
|
||||
find_wpa_ie = 1;
|
||||
break;
|
||||
@ -1383,7 +1383,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
|
||||
/* Test to see if it is a WPS IE, if so, enable
|
||||
* wps session flag
|
||||
*/
|
||||
if (!memcmp(pvendor_ie->oui, wps_oui,
|
||||
if (!memcmp(&pvendor_ie->oui, wps_oui,
|
||||
sizeof(wps_oui))) {
|
||||
priv->wps.session_enable = true;
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
|
@ -240,7 +240,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"info: WMM Parameter IE: version=%d,\t"
|
||||
"qos_info Parameter Set Count=%d, Reserved=%#x\n",
|
||||
wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap &
|
||||
wmm_ie->version, wmm_ie->qos_info_bitmap &
|
||||
IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK,
|
||||
wmm_ie->reserved);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user