qcacld-2.0: Fix potential buffer overflow for TX_COMPL_IND
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
diff --git a/CORE/CLD_TXRX/HTT/htt.h b/CORE/CLD_TXRX/HTT/htt.h
index 03b75ff..351704f 100644
--- a/CORE/CLD_TXRX/HTT/htt.h
+++ b/CORE/CLD_TXRX/HTT/htt.h
@@ -6365,6 +6365,9 @@
#define HTT_TX_COMPL_IND_APPEND2_GET(_info) \
(((_info) & HTT_TX_COMPL_IND_APPEND2_M) >> HTT_TX_COMPL_IND_APPEND2_S)
+#define HTT_TX_COMPL_HEAD_SZ 4
+#define HTT_TX_COMPL_BYTES_PER_MSDU_ID 2
+
#define HTT_TX_COMPL_CTXT_SZ sizeof(A_UINT16)
#define HTT_TX_COMPL_CTXT_NUM(_bytes) ((_bytes) >> 1)
diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c
index d1b97cf..4467ca7 100644
--- a/CORE/CLD_TXRX/HTT/htt_t2h.c
+++ b/CORE/CLD_TXRX/HTT/htt_t2h.c
@@ -640,10 +640,26 @@
{
int num_msdus;
enum htt_tx_status status;
+ int msg_len = adf_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) {
+ adf_os_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;
@@ -730,8 +746,23 @@
case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
{
int num_msdus;
+ int msg_len = adf_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) {
+ adf_os_print("%s: num_msdus(%d) is invalid,"
+ "adf_nbuf_len = %d,inspect\n",
+ __FUNCTION__,
+ num_msdus,
+ msg_len);
+ break;
+ }
+
if (num_msdus & 0x1) {
struct htt_tx_compl_ind_base *compl = (void *)msg_word;