|
@@ -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++;
|
|
|
}
|