Merge android13-gs-pixel-5.10-24Q2 into android13-gs-pixel-5.10

SBMerger: 605678113
Change-Id: Ice2c628f9869a51ecdf9485844e854052caa4fd8
Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
diff --git a/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
index 438708e..331b222 100644
--- a/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
+++ b/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
@@ -273,6 +273,8 @@
 
 #define WLAN_MAX_SRP_IE_LEN                      21
 #define WLAN_MAX_MUEDCA_IE_LEN                   14
+#define WLAN_MIN_HECAP_IE_LEN                    22
+#define WLAN_MAX_HECAP_IE_LEN                    55
 #define WLAN_MAX_HE_6G_CAP_IE_LEN                3
 #define WLAN_MAX_HEOP_IE_LEN                     16
 #define WLAN_HEOP_OUI_TYPE                       "\x24"
@@ -581,6 +583,7 @@
  * @WLAN_EXTN_ELEMID_MUEDCA: MU-EDCA IE
  * @WLAN_EXTN_ELEMID_HE_6G_CAP: HE 6GHz Band Capabilities IE
  * @WLAN_EXTN_ELEMID_SRP:    spatial reuse parameter IE
+ * @WLAN_EXTN_ELEMID_OCI:    OCI IE
  * @WLAN_EXTN_ELEMID_NONINHERITANCE: Non inheritance IE
  * @WLAN_EXTN_ELEMID_EHTOP: EHT Operation IE
  * @WLAN_EXTN_ELEMID_MULTI_LINK: Multi-Link IE
@@ -592,6 +595,7 @@
 	WLAN_EXTN_ELEMID_HEOP        = 36,
 	WLAN_EXTN_ELEMID_MUEDCA      = 38,
 	WLAN_EXTN_ELEMID_SRP         = 39,
+	WLAN_EXTN_ELEMID_OCI         = 54,
 	WLAN_EXTN_ELEMID_NONINHERITANCE = 56,
 	WLAN_EXTN_ELEMID_HE_6G_CAP   = 59,
 	WLAN_EXTN_ELEMID_ESP         = 11,
@@ -1562,6 +1566,8 @@
 #define WLAN_HE_MACCAP_LEN 6
 #define WLAN_HE_PHYCAP_LEN 11
 #define WLAN_HE_MAX_MCS_MAPS 3
+#define WLAN_HE_MCS_MAP_LEN 2
+#define WLAN_INVALID_RX_MCS_MAP 0xFFFF
 /**
  * struct wlan_ie_hecaps - HT capabilities
  * @elem_id: HE caps IE
diff --git a/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c b/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c
index 40c1b16..bc333e3 100644
--- a/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c
+++ b/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c
@@ -3463,7 +3463,8 @@
 	chan_enum = reg_get_chan_enum_for_freq(freq);
 
 	if (chan_enum == INVALID_CHANNEL) {
-		reg_err("chan freq is not valid");
+		if(freq)
+			reg_err("chan freq %d is not valid", freq);
 		return REGULATORY_CHAN_INVALID;
 	}
 
diff --git a/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c
index a2699a5..71361de 100644
--- a/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c
+++ b/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -900,6 +900,9 @@
 		scan_params->ie_list.srp   = (uint8_t *)ie;
 		break;
 	case WLAN_EXTN_ELEMID_HECAP:
+		if ((extn_ie->ie_len < WLAN_MIN_HECAP_IE_LEN) ||
+		    (extn_ie->ie_len > WLAN_MAX_HECAP_IE_LEN))
+			return QDF_STATUS_E_INVAL;
 		scan_params->ie_list.hecap = (uint8_t *)ie;
 		break;
 	case WLAN_EXTN_ELEMID_HEOP:
@@ -1410,7 +1413,7 @@
 }
 
 /**
- * util_scan_scm_update_bss_with_esp_dataa: calculate estimated air time
+ * util_scan_scm_update_bss_with_esp_data: calculate estimated air time
  * fraction
  * @scan_entry: new received entry
  *
@@ -1460,7 +1463,7 @@
 
 /**
  * util_scan_scm_calc_nss_supported_by_ap() - finds out nss from AP
- * @scan_entry: new received entry
+ * @scan_params: new received entry
  *
  * Return: number of nss advertised by AP
  */
@@ -1469,28 +1472,36 @@
 {
 	struct htcap_cmn_ie *htcap;
 	struct wlan_ie_vhtcaps *vhtcaps;
-	struct wlan_ie_hecaps *hecaps;
+	uint8_t *he_cap;
+	uint8_t *end_ptr = NULL;
 	uint16_t rx_mcs_map = 0;
+	uint8_t *mcs_map_offset;
 
 	htcap = (struct htcap_cmn_ie *)
 		util_scan_entry_htcap(scan_params);
 	vhtcaps = (struct wlan_ie_vhtcaps *)
 		util_scan_entry_vhtcap(scan_params);
-	hecaps = (struct wlan_ie_hecaps *)
-		util_scan_entry_hecap(scan_params);
+	he_cap = util_scan_entry_hecap(scan_params);
 
-	if (hecaps) {
+	if (he_cap) {
 		/* Using rx mcs map related to 80MHz or lower as in some
-		 * cases higher mcs may suuport lesser NSS than that
+		 * cases higher mcs may support lesser NSS than that
 		 * of lowe mcs. Thus giving max NSS capability.
 		 */
-		rx_mcs_map =
-			qdf_cpu_to_le16(hecaps->mcs_bw_map[0].rx_mcs_map);
+		end_ptr = he_cap + he_cap[1] + sizeof(struct ie_header);
+		mcs_map_offset = (he_cap + sizeof(struct extn_ie_header) +
+				  WLAN_HE_MACCAP_LEN + WLAN_HE_PHYCAP_LEN);
+		if ((mcs_map_offset + WLAN_HE_MCS_MAP_LEN) <= end_ptr) {
+			rx_mcs_map = *(uint16_t *)mcs_map_offset;
+		} else {
+			rx_mcs_map = WLAN_INVALID_RX_MCS_MAP;
+			scm_debug("mcs_map_offset exceeds he cap len");
+		}
 	} else if (vhtcaps) {
 		rx_mcs_map = vhtcaps->rx_mcs_map;
 	}
 
-	if (hecaps || vhtcaps) {
+	if (he_cap || vhtcaps) {
 		if ((rx_mcs_map & 0xC000) != 0xC000)
 			return 8;
 
@@ -1715,7 +1726,7 @@
 }
 
 #ifdef WLAN_FEATURE_11BE_MLO
-/**
+/*
  * Multi link IE field offsets
  *  ------------------------------------------------------------------------
  * | EID(1) | Len (1) | EID_EXT (1) | ML_CONTROL (2) | CMN_INFO (var) | ... |
@@ -1789,22 +1800,26 @@
 	uint8_t *ml_ie = scan_entry->ie_list.multi_link;
 	uint16_t multi_link_ctrl;
 	uint8_t offset;
+	uint8_t *end_ptr = NULL;
 
 	if (!scan_entry->ie_list.multi_link) {
 		return;
 	}
 
+	end_ptr = ml_ie + ml_ie[TAG_LEN_POS] + sizeof(struct ie_header);
+
 	multi_link_ctrl = *(uint16_t *)(ml_ie + ML_CONTROL_OFFSET);
 
 	/* TODO: update ml_info based on ML IE */
 
-	multi_link_ctrl = *(uint16_t *)(ml_ie + ML_CONTROL_OFFSET);
 	offset = ML_CMN_INFO_OFFSET;
-	/* TODO: Add proper parsing based on presense bitmap */
+	/* TODO: Add proper parsing based on presence bitmap */
 	if (multi_link_ctrl & CMN_INFO_MLD_ADDR_PRESENT_BIT) {
-		qdf_mem_copy(&scan_entry->ml_info.mld_mac_addr,
-			     ml_ie + offset, 6);
-		offset += 6;
+		if ((ml_ie + offset + QDF_MAC_ADDR_SIZE) <= end_ptr) {
+			qdf_mem_copy(&scan_entry->ml_info.mld_mac_addr,
+				     ml_ie + offset, QDF_MAC_ADDR_SIZE);
+			offset += QDF_MAC_ADDR_SIZE;
+		}
 	}
 
 	/* TODO: Decode it from ML IE */
@@ -1814,8 +1829,10 @@
 	 * Copy Link ID & MAC address of the scan cache entry as first entry
 	 * in the partner info list
 	 */
-	if (multi_link_ctrl & CMN_INFO_LINK_ID_PRESENT_BIT)
-		scan_entry->ml_info.self_link_id = ml_ie[offset] & 0x0F;
+	if (multi_link_ctrl & CMN_INFO_LINK_ID_PRESENT_BIT) {
+		if (&ml_ie[offset] < end_ptr)
+			scan_entry->ml_info.self_link_id = ml_ie[offset] & 0x0F;
+	}
 
 	util_get_partner_link_info(scan_entry);
 }
@@ -1906,7 +1923,7 @@
 	scan_entry->bcn_int = le16toh(bcn->beacon_interval);
 
 	/*
-	 * In case if the beacon dosnt have
+	 * In case if the beacon doesn't have
 	 * valid beacon interval falback to def
 	 */
 	if (!scan_entry->bcn_int)
@@ -2563,8 +2580,9 @@
 	 * copied to new ie, skip ssid, capability, bssid-index ie
 	 */
 	tmp_new = sub_copy;
-	while (((tmp_new + tmp_new[1] + MIN_IE_LEN) - sub_copy) <=
-	       subie_len) {
+	while ((subie_len > 0) &&
+	       (((tmp_new + tmp_new[1] + MIN_IE_LEN) - sub_copy) <=
+		(subie_len - 1))) {
 		if (!(tmp_new[0] == WLAN_ELEMID_NONTX_BSSID_CAP ||
 		      tmp_new[0] == WLAN_ELEMID_SSID ||
 		      tmp_new[0] == WLAN_ELEMID_MULTI_BSSID_IDX ||
@@ -3059,9 +3077,10 @@
 		mbssid_ie = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID,
 					      (uint8_t *)&bcn->ie, ie_len);
 		if (mbssid_ie) {
-			if (mbssid_ie[1] <= 0) {
+			/* some APs announce the MBSSID ie_len as 1 */
+			if (mbssid_ie[TAG_LEN_POS] < 1) {
 				scm_debug("MBSSID IE length is wrong %d",
-					  mbssid_ie[1]);
+					  mbssid_ie[TAG_LEN_POS]);
 				return status;
 			}
 			qdf_mem_copy(&mbssid_info.trans_bssid,
diff --git a/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h b/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h
index 8a4251f..332dbd3 100644
--- a/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h
+++ b/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -1871,4 +1871,7 @@
 #define SIR_MAC_TXSTBC                             1
 #define SIR_MAC_RXSTBC                             1
 
+#define SIR_MAC_IE_TYPE_OFFSET                     0
+#define SIR_MAC_IE_LEN_OFFSET                      1
+#define SIR_MAC_IE_TYPE_LEN_SIZE                   2
 #endif /* __MAC_PROT_DEFS_H */
diff --git a/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c b/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c
index 8f83562..537d323 100644
--- a/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -61,6 +61,11 @@
 (DOT11F_FF_CATEGORY_LEN + DOT11F_FF_ACTION_LEN + DOT11F_FF_TRANSACTIONID_LEN)
 #define SA_QUERY_IE_OFFSET (4)
 
+#define MIN_OCI_IE_LEN 6
+#define OCI_IE_OUI_SIZE 1
+#define OCI_IE_OP_CLS_OFFSET 3
+#define ELE_ID_EXT_LEN 1
+
 static last_processed_msg rrm_link_action_frm;
 
 /**-----------------------------------------------------------------
@@ -1213,13 +1218,19 @@
 lim_check_oci_match(struct mac_context *mac, struct pe_session *pe_session,
 		    uint8_t *ie, uint8_t *peer, uint32_t ie_len)
 {
-	const uint8_t *oci_ie;
-	tDot11fIEoci self_oci, *peer_oci;
+	const uint8_t *oci_ie, ext_id_param = WLAN_EXTN_ELEMID_OCI;
+	tDot11fIEoci self_oci, peer_oci = {0};
+	uint32_t status = DOT11F_PARSE_SUCCESS;
 
 	if (!lim_is_self_and_peer_ocv_capable(mac, peer, pe_session))
 		return true;
 
-	oci_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_OCI, ie, ie_len);
+	if (ie_len < MIN_OCI_IE_LEN)
+		return false;
+
+	oci_ie = wlan_get_ext_ie_ptr_from_ext_id(&ext_id_param,
+						 OCI_IE_OUI_SIZE,
+						 ie, ie_len);
 	if (!oci_ie) {
 		pe_err("OCV not found OCI in SA Query frame!");
 		return false;
@@ -1233,19 +1244,25 @@
 	 * Primary channel      : 1 byte
 	 * Freq_seg_1_ch_num    : 1 byte
 	 */
-	peer_oci = (tDot11fIEoci *)&oci_ie[2];
+	status = dot11f_unpack_ie_oci(mac,
+				      (uint8_t *)&oci_ie[OCI_IE_OP_CLS_OFFSET],
+				      oci_ie[SIR_MAC_IE_LEN_OFFSET] -
+				      ELE_ID_EXT_LEN,
+				      &peer_oci, false);
+	if (!DOT11F_SUCCEEDED(status) || !peer_oci.present)
+		return false;
 	lim_fill_oci_params(mac, pe_session, &self_oci);
 
-	if ((self_oci.op_class != peer_oci->op_class) ||
-	    (self_oci.prim_ch_num != peer_oci->prim_ch_num) ||
-	    (self_oci.freq_seg_1_ch_num != peer_oci->freq_seg_1_ch_num)) {
+	if ((self_oci.op_class != peer_oci.op_class) ||
+	    (self_oci.prim_ch_num != peer_oci.prim_ch_num) ||
+	    (self_oci.freq_seg_1_ch_num != peer_oci.freq_seg_1_ch_num)) {
 		pe_err("OCI mismatch,self %d %d %d, peer %d %d %d",
 		       self_oci.op_class,
 		       self_oci.prim_ch_num,
 		       self_oci.freq_seg_1_ch_num,
-		       peer_oci->op_class,
-		       peer_oci->prim_ch_num,
-		       peer_oci->freq_seg_1_ch_num);
+		       peer_oci.op_class,
+		       peer_oci.prim_ch_num,
+		       peer_oci.freq_seg_1_ch_num);
 		return false;
 	}