qcacld-2.0: Fix buffer overflow in htt_t2h_msg_handler_fast

Propagate from qcacld3.0 to qcacld2.0

Currently variable "num_mpdu_ranges" is from message, which is used
directly without any validation which causes buffer over-write.

To avoid buffer over-write add check for the valid num_mpdu_ranges

Change-Id: I54e138d4bd63cbe7a0ae4faf0fe9d8e59ca92c71
CRs-Fixed: 2500393
This commit is contained in:
Lihua Liu 2019-07-31 17:11:44 +08:00 committed by L R
parent c8e905d1ab
commit 4ba2e61837
1 changed files with 30 additions and 0 deletions

View File

@ -625,6 +625,8 @@ if (adf_os_unlikely(pdev->rx_ring.rx_reset)) {
unsigned num_msdu_bytes;
u_int16_t peer_id;
u_int8_t tid;
u_int32_t msg_len = adf_nbuf_len(htt_t2h_msg);
unsigned int calculated_msg_len;
if (adf_os_unlikely(pdev->cfg.is_full_reorder_offload)) {
adf_os_print("HTT_T2H_MSG_TYPE_RX_IND not supported with full "
@ -653,6 +655,34 @@ if (adf_os_unlikely(pdev->rx_ring.rx_reset)) {
num_mpdu_ranges = HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1));
pdev->rx_ind_msdu_byte_idx = 0;
if (unlikely(pdev->rx_mpdu_range_offset_words > msg_len)) {
adf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid rx_mpdu_range_offset_words %d\n",
pdev->rx_mpdu_range_offset_words);
WARN_ON(1);
break;
}
calculated_msg_len = pdev->rx_mpdu_range_offset_words +
(num_mpdu_ranges *
(int)sizeof(uint32_t));
/*
* Check that the addition and multiplication
* do not cause integer overflow
*/
if (unlikely(calculated_msg_len <
pdev->rx_mpdu_range_offset_words)) {
adf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid mpdu_ranges %u\n",
(num_mpdu_ranges *
(int)sizeof(uint32_t)));
WARN_ON(1);
break;
}
if (unlikely(calculated_msg_len > msg_len)) {
adf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid offset_words + mpdu_ranges %u\n",
calculated_msg_len);
WARN_ON(1);
break;
}
if (pdev->cfg.is_high_latency) {
/*
* TODO: remove copy after stopping reuse skb on HIF layer