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

qcacmn: Fix OOB reads in util_gen_new_ie

In util_gen_new_ie, there are several possible out-of-bound reads
with invalid information elements such as improper/missing check when
updating tmp_old, missing check prior to starting while loop and missing
length check.

To fix these OOB issues add and improve length checks in util_gen_new_ie.

Change-Id: I39b9cd82ab6a7bd1a4c8d7cd5039a998a290b85f
CRs-Fixed: 3717568
Krupali Dhanvijay 1 год назад
Родитель
Сommit
cee6125a6d
1 измененных файлов с 12 добавлено и 2 удалено
  1. 12 2
      umac/scan/dispatcher/src/wlan_scan_utils_api.c

+ 12 - 2
umac/scan/dispatcher/src/wlan_scan_utils_api.c

@@ -3102,6 +3102,11 @@ static uint32_t util_gen_new_ie(struct wlan_objmgr_pdev *pdev,
 	tmp_old = util_scan_find_ie(WLAN_ELEMID_SSID, ie, ielen);
 	tmp_old = util_scan_find_ie(WLAN_ELEMID_SSID, ie, ielen);
 	tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + MIN_IE_LEN : ie;
 	tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + MIN_IE_LEN : ie;
 
 
+	if (((tmp_old + MIN_IE_LEN) - ie) >= ielen) {
+		qdf_mem_free(sub_copy);
+		return 0;
+	}
+
 	while (((tmp_old + tmp_old[1] + MIN_IE_LEN) - ie) <= ielen) {
 	while (((tmp_old + tmp_old[1] + MIN_IE_LEN) - ie) <= ielen) {
 		ninh.non_inh_ie_found = 0;
 		ninh.non_inh_ie_found = 0;
 		if (ninh.non_inherit) {
 		if (ninh.non_inherit) {
@@ -3123,6 +3128,9 @@ static uint32_t util_gen_new_ie(struct wlan_objmgr_pdev *pdev,
 		}
 		}
 
 
 		if (ninh.non_inh_ie_found || (tmp_old[0] == 0)) {
 		if (ninh.non_inh_ie_found || (tmp_old[0] == 0)) {
+			if (((tmp_old + tmp_old[1] + MIN_IE_LEN) - ie) >=
+			    (ielen - MIN_IE_LEN))
+				break;
 			tmp_old += tmp_old[1] + MIN_IE_LEN;
 			tmp_old += tmp_old[1] + MIN_IE_LEN;
 			continue;
 			continue;
 		}
 		}
@@ -3176,7 +3184,8 @@ static uint32_t util_gen_new_ie(struct wlan_objmgr_pdev *pdev,
 				 * The copy happens when going through the
 				 * The copy happens when going through the
 				 * remaining IEs.
 				 * remaining IEs.
 				 */
 				 */
-			} else if (tmp_old[0] == WLAN_ELEMID_EXTN_ELEM) {
+			} else if (tmp_old[0] == WLAN_ELEMID_EXTN_ELEM &&
+				   tmp_rem_len >= (MIN_IE_LEN + 1)) {
 				if (tmp_old[PAYLOAD_START_POS] ==
 				if (tmp_old[PAYLOAD_START_POS] ==
 				    tmp[PAYLOAD_START_POS]) {
 				    tmp[PAYLOAD_START_POS]) {
 					/* same ie, copy from subelement */
 					/* same ie, copy from subelement */
@@ -3211,7 +3220,8 @@ static uint32_t util_gen_new_ie(struct wlan_objmgr_pdev *pdev,
 			}
 			}
 		}
 		}
 
 
-		if (((tmp_old + tmp_old[1] + MIN_IE_LEN) - ie) >= ielen)
+		if (((tmp_old + tmp_old[1] + MIN_IE_LEN) - ie) >=
+		    (ielen - MIN_IE_LEN))
 			break;
 			break;
 
 
 		tmp_old += tmp_old[1] + MIN_IE_LEN;
 		tmp_old += tmp_old[1] + MIN_IE_LEN;