summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiger Yu <tfyu@codeaurora.org>2017-12-08 16:39:17 +0800
committersnandini <snandini@codeaurora.org>2017-12-10 22:52:20 -0800
commit92a456fae2748b4d43929faa2bf9d6dbebc8f207 (patch)
tree37aaa0fcb3ff2631bf80a3be1d0471612c93c9e7
parent392dd2d35d13ad94390c0dcb3091746a0afd5dfe (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.c63
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;