@@ -574,39 +574,41 @@ static void cfg80211_free_coloc_ap_list(struct list_head *coloc_ap_list)
574
574
static int cfg80211_parse_ap_info (struct cfg80211_colocated_ap * entry ,
575
575
const u8 * pos , u8 length ,
576
576
const struct element * ssid_elem ,
577
- int s_ssid_tmp )
577
+ u32 s_ssid_tmp )
578
578
{
579
- /* skip the TBTT offset */
580
- pos ++ ;
579
+ u8 bss_params ;
581
580
582
- /* ignore entries with invalid BSSID */
583
- if (!is_valid_ether_addr (pos ))
584
- return - EINVAL ;
585
-
586
- memcpy (entry -> bssid , pos , ETH_ALEN );
587
- pos += ETH_ALEN ;
581
+ /* The length is already verified by the caller to contain bss_params */
582
+ if (length > sizeof (struct ieee80211_tbtt_info_7_8_9 )) {
583
+ struct ieee80211_tbtt_info_ge_11 * tbtt_info = (void * )pos ;
588
584
589
- if (length >= IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM ) {
590
- memcpy (& entry -> short_ssid , pos ,
591
- sizeof (entry -> short_ssid ));
585
+ memcpy (entry -> bssid , tbtt_info -> bssid , ETH_ALEN );
586
+ entry -> short_ssid = le32_to_cpu (tbtt_info -> short_ssid );
592
587
entry -> short_ssid_valid = true;
593
- pos += 4 ;
588
+
589
+ bss_params = tbtt_info -> bss_params ;
590
+ } else {
591
+ struct ieee80211_tbtt_info_7_8_9 * tbtt_info = (void * )pos ;
592
+
593
+ memcpy (entry -> bssid , tbtt_info -> bssid , ETH_ALEN );
594
+
595
+ bss_params = tbtt_info -> bss_params ;
594
596
}
595
597
598
+ /* ignore entries with invalid BSSID */
599
+ if (!is_valid_ether_addr (entry -> bssid ))
600
+ return - EINVAL ;
601
+
596
602
/* skip non colocated APs */
597
- if (!cfg80211_parse_bss_param (* pos , entry ))
603
+ if (!cfg80211_parse_bss_param (bss_params , entry ))
598
604
return - EINVAL ;
599
- pos ++ ;
600
605
601
- if (length == IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM ) {
602
- /*
603
- * no information about the short ssid. Consider the entry valid
604
- * for now. It would later be dropped in case there are explicit
605
- * SSIDs that need to be matched
606
- */
607
- if (!entry -> same_ssid )
608
- return 0 ;
609
- }
606
+ /* no information about the short ssid. Consider the entry valid
607
+ * for now. It would later be dropped in case there are explicit
608
+ * SSIDs that need to be matched
609
+ */
610
+ if (!entry -> same_ssid && !entry -> short_ssid_valid )
611
+ return 0 ;
610
612
611
613
if (entry -> same_ssid ) {
612
614
entry -> short_ssid = s_ssid_tmp ;
@@ -617,10 +619,10 @@ static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
617
619
* cfg80211_parse_colocated_ap(), before calling this
618
620
* function.
619
621
*/
620
- memcpy (& entry -> ssid , & ssid_elem -> data ,
621
- ssid_elem -> datalen );
622
+ memcpy (& entry -> ssid , & ssid_elem -> data , ssid_elem -> datalen );
622
623
entry -> ssid_len = ssid_elem -> datalen ;
623
624
}
625
+
624
626
return 0 ;
625
627
}
626
628
@@ -682,8 +684,11 @@ static int cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies,
682
684
* next AP info
683
685
*/
684
686
if (band != NL80211_BAND_6GHZ ||
685
- (length != IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM &&
686
- length < IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM )) {
687
+ !(length == offsetofend (struct ieee80211_tbtt_info_7_8_9 ,
688
+ bss_params ) ||
689
+ length == sizeof (struct ieee80211_tbtt_info_7_8_9 ) ||
690
+ length >= offsetofend (struct ieee80211_tbtt_info_ge_11 ,
691
+ bss_params ))) {
687
692
pos += count * length ;
688
693
continue ;
689
694
}
0 commit comments