diff options
| author | Vignesh Viswanathan <viswanat@codeaurora.org> | 2017-11-29 14:19:13 +0530 |
|---|---|---|
| committer | Vignesh Viswanathan <viswanat@codeaurora.org> | 2017-11-29 14:24:17 +0530 |
| commit | 00f125a5aab68d1be89afd57eb8a75e06b9a8a12 (patch) | |
| tree | 0eb41bf2b8aada1e3a5e8ff9c534ed2360a1644e | |
| parent | e85f63220316e045e1ca2eb91c635e553bddd273 (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.c | 64 |
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) { |
