From f8317a77ebbff947a033214645babeb1004988c6 Mon Sep 17 00:00:00 2001 From: Vignesh Viswanathan Date: Tue, 24 Oct 2017 22:32:28 +0530 Subject: qcacld-3.0: Fix OOB read in wma_mgmt_tx_bundle_completion_handler In function wma_mgmt_tx_bundle_completion_handler cmpl_params->num_reports, param_buf->desc_ids and param_buf->status are received from the FW. num_reports is used as array index to access desc_ids and status. If the value of num_reports exceeds the max allowed array index, out of bounds access would happen. Add sanity check to make sure num_reports does not exceed the max allowed limit. Also make sure num_reports is not greater than num_desc_ids and num_status Change-Id: I300411febf6449680e873e5947fa767298afe962 CRs-Fixed: 2119439 --- core/wma/src/wma_mgmt.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index d7e1a4648511..bf1c582da59f 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2842,7 +2842,8 @@ int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf, uint32_t num_reports; uint32_t *desc_ids; uint32_t *status; - int i; + uint32_t i, buf_len; + bool excess_data = false; param_buf = (WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *)buf; if (!param_buf || !wma_handle) { @@ -2854,6 +2855,31 @@ int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf, desc_ids = (uint32_t *)(param_buf->desc_ids); status = (uint32_t *)(param_buf->status); + /* buf contains num_reports * sizeof(uint32) len of desc_ids and + * num_reports * sizeof(uint32) status, + * so (2 x (num_reports * sizeof(uint32)) should not exceed MAX + */ + if (cmpl_params->num_reports > (WMI_SVC_MSG_MAX_SIZE / + (2 * sizeof(uint32_t)))) + excess_data = true; + else + buf_len = cmpl_params->num_reports * (2 * sizeof(uint32_t)); + + if (excess_data || (sizeof(*cmpl_params) > (WMI_SVC_MSG_MAX_SIZE - + buf_len))) { + WMA_LOGE("excess wmi buffer: num_reports %d", + cmpl_params->num_reports); + return -EINVAL; + } + + if ((cmpl_params->num_reports > param_buf->num_desc_ids) || + (cmpl_params->num_reports > param_buf->num_status)) { + WMA_LOGE("Invalid num_reports %d, num_desc_ids %d, num_status %d", + cmpl_params->num_reports, param_buf->num_desc_ids, + param_buf->num_status); + return -EINVAL; + } + for (i = 0; i < num_reports; i++) wma_process_mgmt_tx_completion(wma_handle, desc_ids[i], status[i]); -- cgit v1.2.3