summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVignesh Viswanathan <viswanat@codeaurora.org>2017-11-29 14:19:13 +0530
committerVignesh Viswanathan <viswanat@codeaurora.org>2017-11-29 14:24:17 +0530
commit00f125a5aab68d1be89afd57eb8a75e06b9a8a12 (patch)
tree0eb41bf2b8aada1e3a5e8ff9c534ed2360a1644e
parente85f63220316e045e1ca2eb91c635e553bddd273 (diff)
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
-rw-r--r--core/wma/src/wma_scan_roam.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index b361de7ca262..9fb4e8e4f1ef 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -5020,7 +5020,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;
@@ -5042,47 +5042,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_LOGD("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_LOGD("%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 {
@@ -5091,7 +5073,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 {
@@ -5102,11 +5084,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) {