diff options
| author | Tiger Yu <tfyu@codeaurora.org> | 2017-12-08 16:39:17 +0800 |
|---|---|---|
| committer | snandini <snandini@codeaurora.org> | 2017-12-10 22:52:20 -0800 |
| commit | 92a456fae2748b4d43929faa2bf9d6dbebc8f207 (patch) | |
| tree | 37aaa0fcb3ff2631bf80a3be1d0471612c93c9e7 | |
| parent | 392dd2d35d13ad94390c0dcb3091746a0afd5dfe (diff) | |
qcacld-3.0: Fix potential buffer overflow for TX_COMPL_IND
qcacld-2.0 to qcacld-3.0 propagation
Check for the validity of num_msdus when received the htt message of
HTT_T2H_MSG_TYPE_TX_COMPL_IND or HTT_T2H_MSG_TYPE_TX_INSPECT_IND from
firmware to ensure the buffer overflow does not happen.
Change-Id: Ic6ce75f34c5e2705d174eda014350e6ef0391388
CRs-Fixed: 2146869
| -rw-r--r-- | core/dp/htt/htt_t2h.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/core/dp/htt/htt_t2h.c b/core/dp/htt/htt_t2h.c index cd47028448c1..c43ef3aa5d14 100644 --- a/core/dp/htt/htt_t2h.c +++ b/core/dp/htt/htt_t2h.c @@ -618,6 +618,9 @@ static void htt_t2h_rx_in_order_indication_handler( } #endif +#define HTT_TX_COMPL_HEAD_SZ 4 +#define HTT_TX_COMPL_BYTES_PER_MSDU_ID 2 + /** * Generic Target to host Msg/event handler for low priority messages * Low priority message are handler in a different handler called from @@ -709,10 +712,26 @@ void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) int old_credit; int num_msdus; enum htt_tx_status status; + int msg_len = qdf_nbuf_len(htt_t2h_msg); /* status - no enum translation needed */ status = HTT_TX_COMPL_IND_STATUS_GET(*msg_word); num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word); + + /* + * each desc id will occupy 2 bytes. + * the 4 is for htt msg header + */ + if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID + + HTT_TX_COMPL_HEAD_SZ) > msg_len) { + qdf_print("%s: num_msdus(%d) is invalid," + "adf_nbuf_len = %d\n", + __FUNCTION__, + num_msdus, + msg_len); + break; + } + if (num_msdus & 0x1) { struct htt_tx_compl_ind_base *compl = (void *)msg_word; @@ -801,8 +820,23 @@ void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) case HTT_T2H_MSG_TYPE_TX_INSPECT_IND: { int num_msdus; + int msg_len = qdf_nbuf_len(htt_t2h_msg); num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word); + /* + * each desc id will occupy 2 bytes. + * the 4 is for htt msg header + */ + if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID + + HTT_TX_COMPL_HEAD_SZ) > msg_len) { + qdf_print("%s: num_msdus(%d) is invalid," + "adf_nbuf_len = %d\n", + __FUNCTION__, + num_msdus, + msg_len); + break; + } + if (num_msdus & 0x1) { struct htt_tx_compl_ind_base *compl = (void *)msg_word; @@ -948,6 +982,21 @@ void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus, /* status - no enum translation needed */ status = HTT_TX_COMPL_IND_STATUS_GET(*msg_word); num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word); + + /* + * each desc id will occupy 2 bytes. + * the 4 is for htt msg header + */ + if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID + + HTT_TX_COMPL_HEAD_SZ) > msg_len) { + qdf_print("%s: num_msdus(%d) is invalid," + "adf_nbuf_len = %d\n", + __FUNCTION__, + num_msdus, + msg_len); + break; + } + if (num_msdus & 0x1) { struct htt_tx_compl_ind_base *compl = (void *)msg_word; @@ -1007,6 +1056,20 @@ void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus, int num_msdus; num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word); + /* + * each desc id will occupy 2 bytes. + * the 4 is for htt msg header + */ + if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID + + HTT_TX_COMPL_HEAD_SZ) > msg_len) { + qdf_print("%s: num_msdus(%d) is invalid," + "adf_nbuf_len = %d\n", + __FUNCTION__, + num_msdus, + msg_len); + break; + } + if (num_msdus & 0x1) { struct htt_tx_compl_ind_base *compl = (void *)msg_word; |
