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
This commit is contained in:
Tiger Yu 2017-12-08 16:39:17 +08:00 • committed by snandini
commit a007b9a256

View file

@ -582,6 +582,9 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg,
qdf_nbuf_free(htt_t2h_msg);
}
#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
@ -673,10 +676,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;
@ -765,8 +784,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;
@ -933,6 +967,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;
@ -992,6 +1041,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;