Просмотр исходного кода

qcacmn: Update ML per-STA profile IE search offset

Start searching for IEs in the multi-link per-STA
profile from the STA Profile field instead of the
STA Control field to avoid invalid checks that may
arise due to other fields in-between.

CRs-Fixed: 3199541
Change-Id: I0a0f5b6c83135974820d2870e00f6dcf9eab61fe
Aditya Sathish 3 лет назад
Родитель
Сommit
0d8615a6ff
1 измененных файлов с 39 добавлено и 9 удалено
  1. 39 9
      umac/scan/dispatcher/src/wlan_scan_utils_api.c

+ 39 - 9
umac/scan/dispatcher/src/wlan_scan_utils_api.c

@@ -1897,8 +1897,8 @@ static void util_get_partner_link_info(struct scan_cache_entry *scan_entry)
 	uint8_t *ml_ie = scan_entry->ie_list.multi_link;
 	uint8_t offset = util_get_link_info_offset(ml_ie);
 	uint16_t sta_ctrl;
-	uint8_t *stactrl_offset = NULL;
-	uint8_t perstaprof_len = 0;
+	uint8_t *stactrl_offset = NULL, *ielist_offset;
+	uint8_t perstaprof_len = 0, perstaprof_stainfo_len = 0, ielist_len = 0;
 	struct partner_link_info *link_info = NULL;
 	uint8_t eid = 0;
 	uint8_t link_idx = 0;
@@ -1937,11 +1937,41 @@ static void util_get_partner_link_info(struct scan_cache_entry *scan_entry)
 		offset += 2;
 
 		sta_ctrl = *(uint16_t *)(ml_ie + offset);
+
 		/* Skip STA control field */
 		offset += 2;
 
-		 /* Skip STA Info Length field */
-		 offset += WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
+		/*
+		 * offset points to the beginning of the STA Info field which
+		 * holds the length of the variable field.
+		 */
+		perstaprof_stainfo_len = ml_ie[offset];
+
+		/* Skip STA Info Length field */
+		offset += WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
+
+		/*
+		 * To point to the ie_list offset move past the STA Info field.
+		 */
+		ielist_offset  = &ml_ie[offset + perstaprof_stainfo_len];
+
+		/*
+		 * Ensure that the STA Control Field + STA Info Field
+		 * is smaller than the per-STA profile when incrementing
+		 * the pointer to avoid underflow during subtraction.
+		 */
+		if ((perstaprof_stainfo_len +
+		     WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE +
+		     WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE) <
+							perstaprof_len) {
+			ielist_len = perstaprof_len -
+			     (WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE +
+			      WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE +
+			      perstaprof_stainfo_len);
+		} else {
+			scm_debug("No STA profile IE list found");
+			ielist_len = 0;
+		}
 
 		scan_entry->ml_info.link_info[0].link_id = sta_ctrl & 0xF;
 		if (sta_ctrl & LINK_INFO_MAC_ADDR_PRESENT_BIT) {
@@ -1955,16 +1985,16 @@ static void util_get_partner_link_info(struct scan_cache_entry *scan_entry)
 		link_info = &scan_entry->ml_info.link_info[0];
 
 		link_info->csa_ie = wlan_get_ie_ptr_from_eid
-			(WLAN_ELEMID_CHANSWITCHANN, stactrl_offset,
-			 perstaprof_len);
+			(WLAN_ELEMID_CHANSWITCHANN, ielist_offset,
+			 ielist_len);
 
 		link_info->ecsa_ie = wlan_get_ie_ptr_from_eid
-			(WLAN_ELEMID_EXTCHANSWITCHANN, stactrl_offset,
-			 perstaprof_len);
+			(WLAN_ELEMID_EXTCHANSWITCHANN, ielist_offset,
+			 ielist_len);
 
 		eid = WLAN_EXTN_ELEMID_MAX_CHAN_SWITCH_TIME;
 		link_info->max_cst_ie = wlan_get_ext_ie_ptr_from_ext_id
-			(&eid, 1, stactrl_offset, perstaprof_len);
+			(&eid, 1, ielist_offset, ielist_len);
 
 		scan_entry->ml_info.num_links++;
 	}