Jelajahi Sumber

qcacld-3.0: Fix buffer overread in wma_extscan_cached_results_event_handler

In function wma_extscan_cached_results_event_handler,
event->num_entries_in_page is received from the FW and is used in the
function wma_extscan_find_unique_scan_ids to calculate scan_ids_cnt
from src_rssi buffer. If the value of num_entries_in_page is greater
than the number of src_rssi buffers present, a buffer overread would
occur in the function wma_extscan_find_unique_scan_ids.

There is already a check in place to valudate num_entries_in_page in
the function wma_extscan_cached_results_event_handler however it is done
after the call of wma_extscan_find_unique_scan_ids.

Move the checks on num_entries_in_page before using it in the function
wma_extscan_cached_results_event_handler

Change-Id: Ib5e803589deb6ca074cb70326b9ce846d0754a73
CRs-Fixed: 2149720
Vignesh Viswanathan 7 tahun lalu
induk
melakukan
4f75cf5ea5
1 mengubah file dengan 32 tambahan dan 32 penghapusan
  1. 32 32
      core/wma/src/wma_scan_roam.c

+ 32 - 32
core/wma/src/wma_scan_roam.c

@@ -4516,7 +4516,7 @@ int wma_extscan_cached_results_event_handler(void *handle,
 	struct extscan_cached_scan_results empty_cachelist;
 	wmi_extscan_wlan_descriptor *src_hotlist;
 	wmi_extscan_rssi_info *src_rssi;
-	int numap, i, moredata, scan_ids_cnt, buf_len;
+	int i, moredata, scan_ids_cnt, buf_len;
 	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
 	uint32_t total_len;
 	bool excess_data = false;
@@ -4538,47 +4538,29 @@ int wma_extscan_cached_results_event_handler(void *handle,
 	event = param_buf->fixed_param;
 	src_hotlist = param_buf->bssid_list;
 	src_rssi = param_buf->rssi_list;
-	numap = event->num_entries_in_page;
 	WMA_LOGI("Total_entries: %u first_entry_index: %u num_entries_in_page: %d",
 			event->total_entries,
-			event->first_entry_index, numap);
-	if (!src_hotlist || !src_rssi || !numap) {
+			event->first_entry_index,
+			event->num_entries_in_page);
+
+	if (!src_hotlist || !src_rssi || !event->num_entries_in_page) {
 		WMA_LOGW("%s: Cached results empty, send 0 results", __func__);
 		goto noresults;
 	}
-	if (event->first_entry_index +
-	    event->num_entries_in_page < event->total_entries)
-		moredata = 1;
-	else
-		moredata = 0;
-
-	dest_cachelist = qdf_mem_malloc(sizeof(*dest_cachelist));
-	if (!dest_cachelist) {
-		WMA_LOGE("%s: qdf_mem_malloc failed", __func__);
-		return -ENOMEM;
-	}
-	qdf_mem_zero(dest_cachelist, sizeof(*dest_cachelist));
-	dest_cachelist->request_id = event->request_id;
-	dest_cachelist->more_data = moredata;
-
-	scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info);
-	WMA_LOGI("%s: scan_ids_cnt %d", __func__, scan_ids_cnt);
-	dest_cachelist->num_scan_ids = scan_ids_cnt;
 
 	if (event->num_entries_in_page >
-		(WMI_SVC_MSG_MAX_SIZE - sizeof(*event))/sizeof(*src_hotlist)) {
+	    (WMI_SVC_MSG_MAX_SIZE - sizeof(*event))/sizeof(*src_hotlist)) {
 		WMA_LOGE("%s:excess num_entries_in_page %d in WMI event",
-				__func__, event->num_entries_in_page);
-		qdf_mem_free(dest_cachelist);
-		QDF_ASSERT(0);
+			 __func__,
+			 event->num_entries_in_page);
 		return -EINVAL;
 	} else {
 		total_len = sizeof(*event) +
 			(event->num_entries_in_page * sizeof(*src_hotlist));
 	}
 	for (i = 0; i < event->num_entries_in_page; i++) {
-		if (src_hotlist[i].ie_length > WMI_SVC_MSG_MAX_SIZE -
-			total_len) {
+		if (src_hotlist[i].ie_length >
+		    WMI_SVC_MSG_MAX_SIZE - total_len) {
 			excess_data = true;
 			break;
 		} else {
@@ -4587,7 +4569,7 @@ int wma_extscan_cached_results_event_handler(void *handle,
 		}
 
 		if (src_hotlist[i].number_rssi_samples >
-			(WMI_SVC_MSG_MAX_SIZE - total_len)/sizeof(*src_rssi)) {
+		    (WMI_SVC_MSG_MAX_SIZE - total_len) / sizeof(*src_rssi)) {
 			excess_data = true;
 			break;
 		} else {
@@ -4598,11 +4580,29 @@ int wma_extscan_cached_results_event_handler(void *handle,
 	}
 	if (excess_data) {
 		WMA_LOGE("%s:excess data in WMI event",
-				__func__);
-		qdf_mem_free(dest_cachelist);
-		QDF_ASSERT(0);
+			 __func__);
 		return -EINVAL;
 	}
+
+	if (event->first_entry_index +
+	    event->num_entries_in_page < event->total_entries)
+		moredata = 1;
+	else
+		moredata = 0;
+
+	dest_cachelist = qdf_mem_malloc(sizeof(*dest_cachelist));
+	if (!dest_cachelist) {
+		WMA_LOGE("%s: qdf_mem_malloc failed", __func__);
+		return -ENOMEM;
+	}
+	qdf_mem_zero(dest_cachelist, sizeof(*dest_cachelist));
+	dest_cachelist->request_id = event->request_id;
+	dest_cachelist->more_data = moredata;
+
+	scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info);
+	WMA_LOGD("%s: scan_ids_cnt %d", __func__, scan_ids_cnt);
+	dest_cachelist->num_scan_ids = scan_ids_cnt;
+
 	buf_len = sizeof(*dest_result) * scan_ids_cnt;
 	dest_cachelist->result = qdf_mem_malloc(buf_len);
 	if (!dest_cachelist->result) {