From 59f0fad8fe2f003f6958b849b7f71045bc2972e1 Mon Sep 17 00:00:00 2001 From: Vignesh Viswanathan Date: Thu, 25 Jan 2018 17:04:46 +0530 Subject: [PATCH] qcacld-3.0: Fix OOB write in WMA TX power level stats handler In function wma_unified_radio_tx_power_level_stats_event_handler, radio_id is received from the FW in the fixed_param strcutre and is used to access the buffer wma_handle->link_stats_results which is allocated in wma_unified_link_radio_stats_event_handler. The buffer is allocated for link_stats_results->num_radio and if the radio_id received from the FW is greater than link_stats_results->num_radio, an OOB write will occur in wma_unified_radio_tx_power_level_stats_event_handler. Add check to return failure if radio_id received from the FW is greater than link_stats_results->num_radio. Change-Id: I67a848e7ab137d46bb43e7336ff8135da257568c CRs-Fixed: 2169104 --- core/wma/src/wma_utils.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index bdb5bc393280..f920ef43e507 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1448,6 +1448,8 @@ static int wma_unified_radio_tx_power_level_stats_event_handler(void *handle, uint8_t *tx_power_level_values; tSirLLStatsResults *link_stats_results; tSirWifiRadioStat *rs_results; + uint32_t max_total_num_tx_power_levels = MAX_TPC_LEVELS * NUM_OF_BANDS * + MAX_SPATIAL_STREAM_ANY_V3; tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE); @@ -1504,6 +1506,20 @@ static int wma_unified_radio_tx_power_level_stats_event_handler(void *handle, return -EINVAL; } + if (fixed_param->radio_id > link_stats_results->num_radio) { + WMA_LOGD("%s: Invalid radio_id %d num_radio %d", + __func__, fixed_param->radio_id, + link_stats_results->num_radio); + return -EINVAL; + } + + if (fixed_param->total_num_tx_power_levels > + max_total_num_tx_power_levels) { + WMA_LOGD("Invalid total_num_tx_power_levels %d", + fixed_param->total_num_tx_power_levels); + return -EINVAL; + } + rs_results = (tSirWifiRadioStat *) &link_stats_results->results[0] + fixed_param->radio_id; tx_power_level_values = (uint8_t *) param_tlvs->tx_time_per_power_level;