Selaa lähdekoodia

qcacmn: Add individual length checks to Beacon Information element

Currently there is no individual length check to each IE, which
could probably result in buffer overead. Minimum length should
be checked for each varibale IE for avoid the same. Also some fixed
IEs should have a length check of not greater than the size of
their respective structures to avoid corrupting other IE data.

Fix is to add a length check to each individual IE to avoid
corrupting other IEs and also to prevent reception of any IE
of invalid length IE.

Change-Id: I9a0914861d7ff2871ac72ad7357ebbb7ef10eeb3
CRs-Fixed: 2183014
gaurank kathpalia 7 vuotta sitten
vanhempi
sitoutus
7d65c1b32d

+ 36 - 2
umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h

@@ -86,6 +86,27 @@
 #define WLAN_MAX_IE_LEN                255
 #define WLAN_MAX_IE_LEN                255
 #define WLAN_RSN_IE_LEN                22
 #define WLAN_RSN_IE_LEN                22
 
 
+/* Individual element IEs length checks */
+
+#define WLAN_SUPPORTED_RATES_IE_MAX_LEN          8
+#define WLAN_DS_PARAM_IE_MAX_LEN                 1
+#define WLAN_COUNTRY_IE_MIN_LEN                  3
+#define WLAN_QUIET_IE_MAX_LEN                    6
+#define WLAN_CSA_IE_MAX_LEN                      3
+#define WLAN_XCSA_IE_MAX_LEN                     4
+#define WLAN_SECCHANOFF_IE_MAX_LEN               1
+#define WLAN_EXT_SUPPORTED_RATES_IE_MAX_LEN      12
+#define WLAN_EXTCAP_IE_MAX_LEN                   15
+#define WLAN_FILS_INDICATION_IE_MIN_LEN          2
+#define WLAN_MOBILITY_DOMAIN_IE_MAX_LEN          3
+#define WLAN_OPMODE_IE_MAX_LEN                   1
+#define WLAN_IBSSDFS_IE_MIN_LEN                  7
+#define WLAN_EXT_ESP_IE_MAX_LEN                  96
+#define WLAN_HE_CAP_IE_MIN_LEN                   18
+#define WLAN_HE_CAP_IE_MAX_LEN                   53
+#define WLAN_HE_OP_IE_MIN_LEN                     6
+#define WLAN_HE_OP_IE_MAX_LEN                    10
+
 /* HT capability flags */
 /* HT capability flags */
 #define WLAN_HTCAP_C_ADVCODING             0x0001
 #define WLAN_HTCAP_C_ADVCODING             0x0001
 #define WLAN_HTCAP_C_CHWIDTH40             0x0002
 #define WLAN_HTCAP_C_CHWIDTH40             0x0002
@@ -414,6 +435,8 @@ struct wlan_rsn_ie_hdr {
 	u8 version[2];
 	u8 version[2];
 };
 };
 
 
+#define WLAN_RSN_IE_MIN_LEN                    3
+
 /**
 /**
  * struct wlan_rsn_ie: rsn ie info
  * struct wlan_rsn_ie: rsn ie info
  * @ver: RSN ver
  * @ver: RSN ver
@@ -440,6 +463,8 @@ struct wlan_rsn_ie {
 	uint32_t mgmt_cipher_suite;
 	uint32_t mgmt_cipher_suite;
 };
 };
 
 
+#define WLAN_WAPI_IE_MIN_LEN            20
+
 /**
 /**
  * struct wlan_wpa_ie_hdr: wpa ie header
  * struct wlan_wpa_ie_hdr: wpa ie header
  * @elem_id: Wpa element id, vender specific.
  * @elem_id: Wpa element id, vender specific.
@@ -683,9 +708,11 @@ struct fils_indication_ie {
 	uint16_t is_fils_sk_auth_pfs_supported:1;
 	uint16_t is_fils_sk_auth_pfs_supported:1;
 	uint16_t is_pk_auth_supported:1;
 	uint16_t is_pk_auth_supported:1;
 	uint16_t reserved:4;
 	uint16_t reserved:4;
-	uint8_t variable_data[255];
+	uint8_t variable_data[253];
 } qdf_packed;
 } qdf_packed;
 
 
+#define WLAN_VENDOR_HT_IE_OFFSET_LEN    4
+
 /**
 /**
  * struct wlan_vendor_ie_htcap: vendor private HT Capability IE
  * struct wlan_vendor_ie_htcap: vendor private HT Capability IE
  * @id: HT IE
  * @id: HT IE
@@ -776,6 +803,9 @@ struct wlan_vendor_ie_htinfo {
 	struct wlan_ie_htinfo_cmn hi_ie;
 	struct wlan_ie_htinfo_cmn hi_ie;
 } qdf_packed;
 } qdf_packed;
 
 
+#define WLAN_VENDOR_VHTCAP_IE_OFFSET    7
+#define WLAN_VENDOR_VHTOP_IE_OFFSET     21
+
 /**
 /**
  * struct wlan_ie_vhtcaps - VHT capabilities
  * struct wlan_ie_vhtcaps - VHT capabilities
  * @elem_id: VHT caps IE
  * @elem_id: VHT caps IE
@@ -869,12 +899,14 @@ struct wlan_country_ie {
  * struct wlan_country_ie: country IE
  * struct wlan_country_ie: country IE
  * @ie: QBSS IE
  * @ie: QBSS IE
  * @len: IE len
  * @len: IE len
+ * @station_count: number of station associated
  * @qbss_chan_load: qbss channel load
  * @qbss_chan_load: qbss channel load
  * @qbss_load_avail: qbss_load_avail
  * @qbss_load_avail: qbss_load_avail
  */
  */
 struct qbss_load_ie {
 struct qbss_load_ie {
 	uint8_t ie;
 	uint8_t ie;
 	uint8_t len;
 	uint8_t len;
+	uint16_t station_count;
 	uint8_t qbss_chan_load;
 	uint8_t qbss_chan_load;
 	uint16_t qbss_load_avail;
 	uint16_t qbss_load_avail;
 } qdf_packed;
 } qdf_packed;
@@ -893,6 +925,8 @@ struct wlan_bcn_frame {
 	struct ie_header ie;
 	struct ie_header ie;
 } qdf_packed;
 } qdf_packed;
 
 
+#define WLAN_TIM_IE_MIN_LENGTH             4
+
 /**
 /**
  * struct wlan_tim_ie: tim IE
  * struct wlan_tim_ie: tim IE
  * @tim_ie: Time IE
  * @tim_ie: Time IE
@@ -908,7 +942,7 @@ struct wlan_tim_ie {
 	uint8_t tim_count;      /* DTIM count */
 	uint8_t tim_count;      /* DTIM count */
 	uint8_t tim_period;     /* DTIM period */
 	uint8_t tim_period;     /* DTIM period */
 	uint8_t tim_bitctl;     /* bitmap control */
 	uint8_t tim_bitctl;     /* bitmap control */
-	uint8_t tim_bitmap[1];  /* variable-length bitmap */
+	uint8_t tim_bitmap[251];  /* variable-length bitmap */
 } qdf_packed;
 } qdf_packed;
 
 
 /**
 /**

+ 104 - 11
umac/scan/dispatcher/src/wlan_scan_utils_api.c

@@ -341,7 +341,7 @@ util_scan_is_hidden_ssid(struct ie_ssid *ssid)
 	return true;
 	return true;
 }
 }
 
 
-static void
+static QDF_STATUS
 util_scan_parse_extn_ie(struct scan_cache_entry *scan_params,
 util_scan_parse_extn_ie(struct scan_cache_entry *scan_params,
 	struct ie_header *ie)
 	struct ie_header *ie)
 {
 {
@@ -352,24 +352,32 @@ util_scan_parse_extn_ie(struct scan_cache_entry *scan_params,
 		scan_params->ie_list.srp   = (uint8_t *)ie;
 		scan_params->ie_list.srp   = (uint8_t *)ie;
 		break;
 		break;
 	case WLAN_EXTN_ELEMID_HECAP:
 	case WLAN_EXTN_ELEMID_HECAP:
+		if ((extn_ie->ie_len < WLAN_HE_CAP_IE_MIN_LEN) ||
+		    (extn_ie->ie_len > WLAN_HE_CAP_IE_MAX_LEN))
+			return QDF_STATUS_E_INVAL;
 		scan_params->ie_list.hecap = (uint8_t *)ie;
 		scan_params->ie_list.hecap = (uint8_t *)ie;
 		break;
 		break;
 	case WLAN_EXTN_ELEMID_HEOP:
 	case WLAN_EXTN_ELEMID_HEOP:
+		if ((extn_ie->ie_len < WLAN_HE_OP_IE_MIN_LEN) ||
+		    (extn_ie->ie_len > WLAN_HE_OP_IE_MAX_LEN))
+			return QDF_STATUS_E_INVAL;
 		scan_params->ie_list.heop  = (uint8_t *)ie;
 		scan_params->ie_list.heop  = (uint8_t *)ie;
 		break;
 		break;
 	case WLAN_EXTN_ELEMID_ESP:
 	case WLAN_EXTN_ELEMID_ESP:
+		if (extn_ie->ie_len > WLAN_EXT_ESP_IE_MAX_LEN)
+			return QDF_STATUS_E_INVAL;
 		scan_params->ie_list.esp = (uint8_t *)ie;
 		scan_params->ie_list.esp = (uint8_t *)ie;
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;
 	}
 	}
+	return QDF_STATUS_SUCCESS;
 }
 }
 
 
-static void
+static QDF_STATUS
 util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params,
 util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params,
 	struct ie_header *ie)
 	struct ie_header *ie)
 {
 {
-
 	if (scan_params->ie_list.vendor == NULL)
 	if (scan_params->ie_list.vendor == NULL)
 		scan_params->ie_list.vendor = (uint8_t *)ie;
 		scan_params->ie_list.vendor = (uint8_t *)ie;
 
 
@@ -397,20 +405,51 @@ util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params,
 		scan_params->ie_list.sonadv = (uint8_t *)ie;
 		scan_params->ie_list.sonadv = (uint8_t *)ie;
 	} else if (is_ht_cap((uint8_t *)ie)) {
 	} else if (is_ht_cap((uint8_t *)ie)) {
 		/* we only care if there isn't already an HT IE (ANA) */
 		/* we only care if there isn't already an HT IE (ANA) */
-		if (scan_params->ie_list.htcap == NULL)
+		if (scan_params->ie_list.htcap == NULL) {
+			if (ie->ie_len != (WLAN_VENDOR_HT_IE_OFFSET_LEN +
+					   sizeof(struct htcap_cmn_ie)))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.htcap =
 			scan_params->ie_list.htcap =
-			  (uint8_t *)&(((struct wlan_vendor_ie_htcap *)ie)->ie);
+			 (uint8_t *)&(((struct wlan_vendor_ie_htcap *)ie)->ie);
+		}
 	} else if (is_ht_info((uint8_t *)ie)) {
 	} else if (is_ht_info((uint8_t *)ie)) {
 		/* we only care if there isn't already an HT IE (ANA) */
 		/* we only care if there isn't already an HT IE (ANA) */
-		if (scan_params->ie_list.htinfo == NULL)
+		if (scan_params->ie_list.htinfo == NULL) {
+			if (ie->ie_len != WLAN_VENDOR_HT_IE_OFFSET_LEN +
+					  sizeof(struct wlan_ie_htinfo_cmn))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.htinfo =
 			scan_params->ie_list.htinfo =
 			  (uint8_t *)&(((struct wlan_vendor_ie_htinfo *)
 			  (uint8_t *)&(((struct wlan_vendor_ie_htinfo *)
 			  ie)->hi_ie);
 			  ie)->hi_ie);
+		}
 	} else if (is_interop_vht((uint8_t *)ie) &&
 	} else if (is_interop_vht((uint8_t *)ie) &&
 	    !(scan_params->ie_list.vhtop)) {
 	    !(scan_params->ie_list.vhtop)) {
+		uint8_t *vendor_ie = (uint8_t *)(ie);
+
+		if (ie->ie_len < ((WLAN_VENDOR_VHTCAP_IE_OFFSET +
+				 sizeof(struct wlan_ie_vhtcaps)) -
+				 sizeof(struct ie_header)))
+			return QDF_STATUS_E_INVAL;
+		vendor_ie = ((uint8_t *)(ie)) + WLAN_VENDOR_VHTCAP_IE_OFFSET;
+		if (vendor_ie[1] != (sizeof(struct wlan_ie_vhtcaps)) -
+				      sizeof(struct ie_header))
+			return QDF_STATUS_E_INVAL;
 		/* location where Interop Vht Cap IE and VHT OP IE Present */
 		/* location where Interop Vht Cap IE and VHT OP IE Present */
-		scan_params->ie_list.vhtcap = (((uint8_t *)(ie)) + 7);
-		scan_params->ie_list.vhtop = (((uint8_t *)(ie)) + 21);
+		scan_params->ie_list.vhtcap = (((uint8_t *)(ie)) +
+						WLAN_VENDOR_VHTCAP_IE_OFFSET);
+		if (ie->ie_len > ((WLAN_VENDOR_VHTCAP_IE_OFFSET +
+				 sizeof(struct wlan_ie_vhtcaps)) -
+				 sizeof(struct ie_header)) &&
+		    ie->ie_len < ((WLAN_VENDOR_VHTOP_IE_OFFSET +
+				  sizeof(struct wlan_ie_vhtop)) -
+				  sizeof(struct ie_header)))
+			return QDF_STATUS_E_INVAL;
+		vendor_ie = ((uint8_t *)(ie)) + WLAN_VENDOR_VHTOP_IE_OFFSET;
+		if (vendor_ie[1] != (sizeof(struct wlan_ie_vhtop) -
+				     sizeof(struct ie_header)))
+			return QDF_STATUS_E_INVAL;
+		scan_params->ie_list.vhtop = (((uint8_t *)(ie)) +
+						WLAN_VENDOR_VHTOP_IE_OFFSET);
 	} else if (is_bwnss_oui((uint8_t *)ie)) {
 	} else if (is_bwnss_oui((uint8_t *)ie)) {
 		/*
 		/*
 		 * Bandwidth-NSS map has sub-type & version.
 		 * Bandwidth-NSS map has sub-type & version.
@@ -420,6 +459,7 @@ util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params,
 	} else if (is_mbo_oce_oui((uint8_t *)ie)) {
 	} else if (is_mbo_oce_oui((uint8_t *)ie)) {
 		scan_params->ie_list.mbo_oce = (uint8_t *)ie;
 		scan_params->ie_list.mbo_oce = (uint8_t *)ie;
 	}
 	}
+	return QDF_STATUS_SUCCESS;
 }
 }
 
 
 static QDF_STATUS
 static QDF_STATUS
@@ -449,56 +489,89 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params)
 
 
 		switch (ie->ie_id) {
 		switch (ie->ie_id) {
 		case WLAN_ELEMID_SSID:
 		case WLAN_ELEMID_SSID:
+			if (ie->ie_len > (sizeof(struct ie_ssid) -
+					  sizeof(struct ie_header)))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.ssid = (uint8_t *)ie;
 			scan_params->ie_list.ssid = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_RATES:
 		case WLAN_ELEMID_RATES:
+			if (ie->ie_len > WLAN_SUPPORTED_RATES_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.rates = (uint8_t *)ie;
 			scan_params->ie_list.rates = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_DSPARMS:
 		case WLAN_ELEMID_DSPARMS:
+			if (ie->ie_len != WLAN_DS_PARAM_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.ds_param = (uint8_t *)ie;
 			scan_params->ie_list.ds_param = (uint8_t *)ie;
 			scan_params->channel.chan_idx =
 			scan_params->channel.chan_idx =
 				((struct ds_ie *)ie)->cur_chan;
 				((struct ds_ie *)ie)->cur_chan;
 			break;
 			break;
 		case WLAN_ELEMID_TIM:
 		case WLAN_ELEMID_TIM:
+			if (ie->ie_len < WLAN_TIM_IE_MIN_LENGTH)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.tim = (uint8_t *)ie;
 			scan_params->ie_list.tim = (uint8_t *)ie;
 			scan_params->dtim_period =
 			scan_params->dtim_period =
 				((struct wlan_tim_ie *)ie)->tim_period;
 				((struct wlan_tim_ie *)ie)->tim_period;
 			break;
 			break;
 		case WLAN_ELEMID_COUNTRY:
 		case WLAN_ELEMID_COUNTRY:
+			if (ie->ie_len < WLAN_COUNTRY_IE_MIN_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.country = (uint8_t *)ie;
 			scan_params->ie_list.country = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_QBSS_LOAD:
 		case WLAN_ELEMID_QBSS_LOAD:
+			if (ie->ie_len != sizeof(struct qbss_load_ie) -
+					  sizeof(struct ie_header))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.qbssload = (uint8_t *)ie;
 			scan_params->ie_list.qbssload = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_CHANSWITCHANN:
 		case WLAN_ELEMID_CHANSWITCHANN:
+			if (ie->ie_len != WLAN_CSA_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.csa = (uint8_t *)ie;
 			scan_params->ie_list.csa = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_IBSSDFS:
 		case WLAN_ELEMID_IBSSDFS:
+			if (ie->ie_len < WLAN_IBSSDFS_IE_MIN_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.ibssdfs = (uint8_t *)ie;
 			scan_params->ie_list.ibssdfs = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_QUIET:
 		case WLAN_ELEMID_QUIET:
+			if (ie->ie_len != WLAN_QUIET_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.quiet = (uint8_t *)ie;
 			scan_params->ie_list.quiet = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_ERP:
 		case WLAN_ELEMID_ERP:
+			if (ie->ie_len != (sizeof(struct erp_ie) -
+					    sizeof(struct ie_header)))
+				return QDF_STATUS_E_INVAL;
 			scan_params->erp = ((struct erp_ie *)ie)->value;
 			scan_params->erp = ((struct erp_ie *)ie)->value;
 			break;
 			break;
 		case WLAN_ELEMID_HTCAP_ANA:
 		case WLAN_ELEMID_HTCAP_ANA:
+			if (ie->ie_len != sizeof(struct htcap_cmn_ie))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.htcap =
 			scan_params->ie_list.htcap =
 				(uint8_t *)&(((struct htcap_ie *)ie)->ie);
 				(uint8_t *)&(((struct htcap_ie *)ie)->ie);
 			break;
 			break;
 		case WLAN_ELEMID_RSN:
 		case WLAN_ELEMID_RSN:
+			if (ie->ie_len < WLAN_RSN_IE_MIN_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.rsn = (uint8_t *)ie;
 			scan_params->ie_list.rsn = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_XRATES:
 		case WLAN_ELEMID_XRATES:
 			scan_params->ie_list.xrates = (uint8_t *)ie;
 			scan_params->ie_list.xrates = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_EXTCHANSWITCHANN:
 		case WLAN_ELEMID_EXTCHANSWITCHANN:
+			if (ie->ie_len != WLAN_XCSA_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.xcsa = (uint8_t *)ie;
 			scan_params->ie_list.xcsa = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_SECCHANOFFSET:
 		case WLAN_ELEMID_SECCHANOFFSET:
+			if (ie->ie_len != WLAN_SECCHANOFF_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.secchanoff = (uint8_t *)ie;
 			scan_params->ie_list.secchanoff = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_HTINFO_ANA:
 		case WLAN_ELEMID_HTINFO_ANA:
+			if (ie->ie_len != sizeof(struct wlan_ie_htinfo_cmn))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.htinfo =
 			scan_params->ie_list.htinfo =
 			  (uint8_t *)&(((struct wlan_ie_htinfo *) ie)->hi_ie);
 			  (uint8_t *)&(((struct wlan_ie_htinfo *) ie)->hi_ie);
 			scan_params->channel.chan_idx =
 			scan_params->channel.chan_idx =
@@ -506,26 +579,42 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params)
 			  (scan_params->ie_list.htinfo))->hi_ctrlchannel;
 			  (scan_params->ie_list.htinfo))->hi_ctrlchannel;
 			break;
 			break;
 		case WLAN_ELEMID_WAPI:
 		case WLAN_ELEMID_WAPI:
+			if (ie->ie_len < WLAN_WAPI_IE_MIN_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.wapi = (uint8_t *)ie;
 			scan_params->ie_list.wapi = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_XCAPS:
 		case WLAN_ELEMID_XCAPS:
+			if (ie->ie_len > WLAN_EXTCAP_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.extcaps = (uint8_t *)ie;
 			scan_params->ie_list.extcaps = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_VHTCAP:
 		case WLAN_ELEMID_VHTCAP:
+			if (ie->ie_len != (sizeof(struct wlan_ie_vhtcaps) -
+					   sizeof(struct ie_header)))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.vhtcap = (uint8_t *)ie;
 			scan_params->ie_list.vhtcap = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_VHTOP:
 		case WLAN_ELEMID_VHTOP:
+			if (ie->ie_len != (sizeof(struct wlan_ie_vhtop) -
+					   sizeof(struct ie_header)))
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.vhtop = (uint8_t *)ie;
 			scan_params->ie_list.vhtop = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_OP_MODE_NOTIFY:
 		case WLAN_ELEMID_OP_MODE_NOTIFY:
+			if (ie->ie_len != WLAN_OPMODE_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 				scan_params->ie_list.opmode = (uint8_t *)ie;
 				scan_params->ie_list.opmode = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_MOBILITY_DOMAIN:
 		case WLAN_ELEMID_MOBILITY_DOMAIN:
+			if (ie->ie_len != WLAN_MOBILITY_DOMAIN_IE_MAX_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.mdie = (uint8_t *)ie;
 			scan_params->ie_list.mdie = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_VENDOR:
 		case WLAN_ELEMID_VENDOR:
-			util_scan_parse_vendor_ie(scan_params,
-				ie);
+			status = util_scan_parse_vendor_ie(scan_params,
+							   ie);
+			if (QDF_IS_STATUS_ERROR(status))
+				return status;
 			break;
 			break;
 		case WLAN_ELEMID_CHAN_SWITCH_WRAP:
 		case WLAN_ELEMID_CHAN_SWITCH_WRAP:
 			scan_params->ie_list.cswrp = (uint8_t *)ie;
 			scan_params->ie_list.cswrp = (uint8_t *)ie;
@@ -542,10 +631,14 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params)
 			}
 			}
 			break;
 			break;
 		case WLAN_ELEMID_FILS_INDICATION:
 		case WLAN_ELEMID_FILS_INDICATION:
+			if (ie->ie_len < WLAN_FILS_INDICATION_IE_MIN_LEN)
+				return QDF_STATUS_E_INVAL;
 			scan_params->ie_list.fils_indication = (uint8_t *)ie;
 			scan_params->ie_list.fils_indication = (uint8_t *)ie;
 			break;
 			break;
 		case WLAN_ELEMID_EXTN_ELEM:
 		case WLAN_ELEMID_EXTN_ELEM:
-			util_scan_parse_extn_ie(scan_params, ie);
+			status = util_scan_parse_extn_ie(scan_params, ie);
+			if (QDF_IS_STATUS_ERROR(status))
+				return status;
 			break;
 			break;
 		default:
 		default:
 			break;
 			break;