Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63d7ef36 authored by Brian Norris's avatar Brian Norris Committed by Kalle Valo
Browse files

mwifiex: Don't abort on small, spec-compliant vendor IEs



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: 685c9b77 ("mwifiex: Abort at too short BSS descriptor element")
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 608fd721
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -1759,9 +1759,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 {
@@ -1775,6 +1776,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];
@@ -1792,6 +1796,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;
+11 −7
Original line number Diff line number Diff line
@@ -1361,21 +1361,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,
			/* 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) ||
+2 −2
Original line number Diff line number Diff line
@@ -1351,7 +1351,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))) {
				/* IE is a WPA/WPA2 IE so call set_wpa function
				 */
@@ -1361,7 +1361,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
				goto next_ie;
			}

			if (!memcmp(pvendor_ie->oui, wps_oui,
			if (!memcmp(&pvendor_ie->oui, wps_oui,
				    sizeof(wps_oui))) {
				/* Test to see if it is a WPS IE,
				 * if so, enable wps session flag
+1 −1
Original line number Diff line number Diff line
@@ -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);