diff options
| author | Arif Hussain <arifhussain@codeaurora.org> | 2019-01-24 12:36:26 -0800 |
|---|---|---|
| committer | nshrivas <nshrivas@codeaurora.org> | 2019-04-18 03:09:59 -0700 |
| commit | 2035546623bc2339d743ee62bc4d9521ca2cf6ca (patch) | |
| tree | b56af18ada364259b8b7bc15b698ec115e5725e4 | |
| parent | aa0e0154ca4290ecd987c5c27b0bc35046fad735 (diff) | |
qcacld-3.0: Fix possible OOB read in stats event handler
Fix possible OOB read while handling
WMI_REPORT_STATS_EVENTID from firmware.
Change-Id: I9c6efae3bc11447aeb36bd9c4db43848e277f86f
CRs-Fixed: 2382056
| -rw-r--r-- | core/wma/src/wma_utils.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index dcb093dd7314..7fc33d40bf42 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -832,8 +832,9 @@ wma_fill_tx_stats(struct sir_wifi_ll_ext_stats *ll_stats, struct sir_wifi_tx *tx_stats; struct sir_wifi_ll_ext_peer_stats *peer_stats; uint32_t *tx_mpdu_aggr, *tx_succ_mcs, *tx_fail_mcs, *tx_delay; - uint32_t len, dst_len, tx_mpdu_aggr_array_len, tx_succ_mcs_array_len, - tx_fail_mcs_array_len, tx_delay_array_len; + uint32_t len, dst_len, param_len, tx_mpdu_aggr_array_len, + tx_succ_mcs_array_len, tx_fail_mcs_array_len, + tx_delay_array_len; result = *buf; dst_len = *buf_length; @@ -850,49 +851,57 @@ wma_fill_tx_stats(struct sir_wifi_ll_ext_stats *ll_stats, len = fix_param->num_peer_ac_tx_stats * WLAN_MAX_AC * tx_mpdu_aggr_array_len * sizeof(uint32_t); - if (len <= dst_len && param_buf->tx_mpdu_aggr) { + param_len = param_buf->num_tx_mpdu_aggr * sizeof(uint32_t); + if (len <= dst_len && len <= param_len && param_buf->tx_mpdu_aggr) { tx_mpdu_aggr = (uint32_t *)result; qdf_mem_copy(tx_mpdu_aggr, param_buf->tx_mpdu_aggr, len); result += len; dst_len -= len; } else { - WMA_LOGE(FL("TX_MPDU_AGGR invalid arg, %d, %d"), len, dst_len); + WMA_LOGE(FL("TX_MPDU_AGGR invalid arg, %d, %d, %d"), + len, dst_len, param_len); return QDF_STATUS_E_FAILURE; } len = fix_param->num_peer_ac_tx_stats * WLAN_MAX_AC * tx_succ_mcs_array_len * sizeof(uint32_t); - if (len <= dst_len && param_buf->tx_succ_mcs) { + param_len = param_buf->num_tx_succ_mcs * sizeof(uint32_t); + if (len <= dst_len && len <= param_len && param_buf->tx_succ_mcs) { tx_succ_mcs = (uint32_t *)result; qdf_mem_copy(tx_succ_mcs, param_buf->tx_succ_mcs, len); result += len; dst_len -= len; } else { - WMA_LOGE(FL("TX_SUCC_MCS invalid arg, %d, %d"), len, dst_len); + WMA_LOGE(FL("TX_SUCC_MCS invalid arg, %d, %d, %d"), + len, dst_len, param_len); return QDF_STATUS_E_FAILURE; } len = fix_param->num_peer_ac_tx_stats * WLAN_MAX_AC * tx_fail_mcs_array_len * sizeof(uint32_t); - if (len <= dst_len && param_buf->tx_fail_mcs) { + param_len = param_buf->num_tx_fail_mcs * sizeof(uint32_t); + if (len <= dst_len && len <= param_len && param_buf->tx_fail_mcs) { tx_fail_mcs = (uint32_t *)result; qdf_mem_copy(tx_fail_mcs, param_buf->tx_fail_mcs, len); result += len; dst_len -= len; } else { - WMA_LOGE(FL("TX_FAIL_MCS invalid arg, %d, %d"), len, dst_len); + WMA_LOGE(FL("TX_FAIL_MCS invalid arg, %d, %d %d"), + len, dst_len, param_len); return QDF_STATUS_E_FAILURE; } len = fix_param->num_peer_ac_tx_stats * WLAN_MAX_AC * tx_delay_array_len * sizeof(uint32_t); - if (len <= dst_len && param_buf->tx_ppdu_delay) { + param_len = param_buf->num_tx_ppdu_delay * sizeof(uint32_t); + if (len <= dst_len && len <= param_len && param_buf->tx_ppdu_delay) { tx_delay = (uint32_t *)result; qdf_mem_copy(tx_delay, param_buf->tx_ppdu_delay, len); result += len; dst_len -= len; } else { - WMA_LOGE(FL("TX_DELAY invalid arg, %d, %d"), len, dst_len); + WMA_LOGE(FL("TX_DELAY invalid arg, %d, %d, %d"), + len, dst_len, param_len); return QDF_STATUS_E_FAILURE; } @@ -986,7 +995,8 @@ wma_fill_rx_stats(struct sir_wifi_ll_ext_stats *ll_stats, wmi_peer_ac_rx_stats *wmi_peer_rx; struct sir_wifi_rx *rx_stats; struct sir_wifi_ll_ext_peer_stats *peer_stats; - uint32_t len, dst_len, rx_mpdu_aggr_array_len, rx_mcs_array_len; + uint32_t len, dst_len, param_len, + rx_mpdu_aggr_array_len, rx_mcs_array_len; rx_mpdu_aggr_array_len = fix_param->rx_mpdu_aggr_array_len; ll_stats->rx_mpdu_aggr_array_len = rx_mpdu_aggr_array_len; @@ -999,25 +1009,29 @@ wma_fill_rx_stats(struct sir_wifi_ll_ext_stats *ll_stats, dst_len = *buf_length; len = sizeof(uint32_t) * (fix_param->num_peer_ac_rx_stats * WLAN_MAX_AC * rx_mpdu_aggr_array_len); - if (len <= dst_len && param_buf->rx_mpdu_aggr) { + param_len = param_buf->num_rx_mpdu_aggr * sizeof(uint32_t); + if (len <= dst_len && len <= param_len && param_buf->rx_mpdu_aggr) { rx_mpdu_aggr = (uint32_t *)result; qdf_mem_copy(rx_mpdu_aggr, param_buf->rx_mpdu_aggr, len); result += len; dst_len -= len; } else { - WMA_LOGE(FL("RX_MPDU_AGGR invalid arg %d, %d"), len, dst_len); + WMA_LOGE(FL("RX_MPDU_AGGR invalid arg %d, %d, %d"), + len, dst_len, param_len); return QDF_STATUS_E_FAILURE; } len = sizeof(uint32_t) * (fix_param->num_peer_ac_rx_stats * WLAN_MAX_AC * rx_mcs_array_len); - if (len <= dst_len && param_buf->rx_mcs) { + param_len = param_buf->num_rx_mcs * sizeof(uint32_t); + if (len <= dst_len && len <= param_len && param_buf->rx_mcs) { rx_mcs = (uint32_t *)result; qdf_mem_copy(rx_mcs, param_buf->rx_mcs, len); result += len; dst_len -= len; } else { - WMA_LOGE(FL("RX_MCS invalid arg %d, %d"), len, dst_len); + WMA_LOGE(FL("RX_MCS invalid arg %d, %d, %d"), + len, dst_len, param_len); return QDF_STATUS_E_FAILURE; } |
