diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 4a4ec1abc749..b67bcfbe8ca1 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2901,7 +2901,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) { @@ -2913,6 +2914,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]);