From 10ff2ff9ed34dae7538a2b0b630f55ad3a3de9fd Mon Sep 17 00:00:00 2001 From: jitiphil Date: Thu, 5 Apr 2018 23:53:10 +0530 Subject: [PATCH] qcacld-3.0: Fix buffer overflow in htt_t2h_msg_handler_fast 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: 2213655 --- core/dp/htt/htt_t2h.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/core/dp/htt/htt_t2h.c b/core/dp/htt/htt_t2h.c index e1ee00a26212..3740f2b49686 100644 --- a/core/dp/htt/htt_t2h.c +++ b/core/dp/htt/htt_t2h.c @@ -993,8 +993,10 @@ void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus, { unsigned int num_mpdu_ranges; unsigned int num_msdu_bytes; + unsigned int calculated_msg_len; u_int16_t peer_id; u_int8_t tid; + msg_len = qdf_nbuf_len(htt_t2h_msg); peer_id = HTT_RX_IND_PEER_ID_GET(*msg_word); tid = HTT_RX_IND_EXT_TID_GET(*msg_word); @@ -1004,7 +1006,6 @@ void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus, WARN_ON(1); break; } - num_msdu_bytes = HTT_RX_IND_FW_RX_DESC_BYTES_GET( *(msg_word + 2 + @@ -1024,6 +1025,34 @@ void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus, HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1)); pdev->rx_ind_msdu_byte_idx = 0; + if (qdf_unlikely(pdev->rx_mpdu_range_offset_words > + msg_len)) { + qdf_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 (qdf_unlikely(calculated_msg_len < + pdev->rx_mpdu_range_offset_words)) { + qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid mpdu_ranges %u\n", + (num_mpdu_ranges * + (int)sizeof(uint32_t))); + WARN_ON(1); + break; + } + if (qdf_unlikely(calculated_msg_len > msg_len)) { + qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid offset_words + mpdu_ranges %u\n", + calculated_msg_len); + WARN_ON(1); + break; + } ol_rx_indication_handler(pdev->txrx_pdev, htt_t2h_msg, peer_id, tid, num_mpdu_ranges); break;