Browse Source

qcacld-3.0: Fix potential buffer overflow in ol_rx_flush_handler

qcacld-2.0 to qcacld-3.0 propagation

Check for the validity of tid when received the htt message of
HTT_T2H_MSG_TYPE_RX_FLUSH & HTT_T2H_MSG_TYPE_RX_PN_IND from firmware
to ensure the buffer overflow does not happen.

And correct the sequence number type from signed int to unsigned.

Change-Id: Ibff86e891c335bfe8c2f9db82410545036463ed3
CRs-Fixed: 2149399
Tiger Yu 7 years ago
parent
commit
62ef4fb08d

+ 3 - 3
core/dp/htt/htt_t2h.c

@@ -236,7 +236,7 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg,
 	{
 		uint16_t peer_id;
 		uint8_t tid;
-		int seq_num_start, seq_num_end;
+		uint16_t seq_num_start, seq_num_end;
 		enum htt_rx_flush_action action;
 
 		peer_id = HTT_RX_FLUSH_PEER_ID_GET(*msg_word);
@@ -757,7 +757,7 @@ void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
 	{
 		uint16_t peer_id;
 		uint8_t tid, pn_ie_cnt, *pn_ie = NULL;
-		int seq_num_start, seq_num_end;
+		uint16_t seq_num_start, seq_num_end;
 
 		/*First dword */
 		peer_id = HTT_RX_PN_IND_PEER_ID_GET(*msg_word);
@@ -1433,7 +1433,7 @@ htt_t2h_dbg_stats_hdr_parse(uint8_t *stats_info_list,
 void
 htt_rx_frag_ind_flush_seq_num_range(htt_pdev_handle pdev,
 				    qdf_nbuf_t rx_frag_ind_msg,
-				    int *seq_num_start, int *seq_num_end)
+				    uint16_t *seq_num_start, uint16_t *seq_num_end)
 {
 	uint32_t *msg_word;
 

+ 1 - 1
core/dp/ol/inc/ol_htt_rx_api.h

@@ -843,7 +843,7 @@ htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
 void
 htt_rx_frag_ind_flush_seq_num_range(htt_pdev_handle pdev,
 				    qdf_nbuf_t rx_frag_ind_msg,
-				    int *seq_num_start, int *seq_num_end);
+				    uint16_t *seq_num_start, uint16_t *seq_num_end);
 
 /**
  * htt_rx_msdu_rx_desc_size_hl() - Return the HL rx desc size

+ 2 - 2
core/dp/ol/inc/ol_txrx_htt_api.h

@@ -623,8 +623,8 @@ void
 ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev,
 		     uint16_t peer_id,
 		     uint8_t tid,
-		     int seq_num_start,
-		     int seq_num_end, uint8_t pn_ie_cnt, uint8_t *pn_ie);
+		     uint16_t seq_num_start,
+		     uint16_t seq_num_end, uint8_t pn_ie_cnt, uint8_t *pn_ie);
 
 /**
  * @brief Process a stats message sent by the target.

+ 7 - 2
core/dp/txrx/ol_rx_defrag.c

@@ -324,7 +324,7 @@ ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev,
 			      uint16_t peer_id, uint8_t tid)
 {
 	uint16_t seq_num;
-	int seq_num_start, seq_num_end;
+	uint16_t seq_num_start, seq_num_end;
 	struct ol_txrx_peer_t *peer;
 	htt_pdev_handle htt_pdev;
 	qdf_nbuf_t head_msdu, tail_msdu;
@@ -333,6 +333,11 @@ ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev,
 	uint32_t msdu_count = 0;
 	int ret;
 
+	if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+		ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+		return;
+	}
+
 	htt_pdev = pdev->htt_pdev;
 	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
 
@@ -392,7 +397,7 @@ ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev,
 void
 ol_rx_reorder_flush_frag(htt_pdev_handle htt_pdev,
 			 struct ol_txrx_peer_t *peer,
-			 unsigned int tid, int seq_num)
+			 unsigned int tid, uint16_t seq_num)
 {
 	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
 	int seq;

+ 1 - 1
core/dp/txrx/ol_rx_defrag.h

@@ -125,7 +125,7 @@ ol_rx_defrag_mic(ol_txrx_pdev_handle pdev,
 void
 ol_rx_reorder_flush_frag(htt_pdev_handle htt_pdev,
 			 struct ol_txrx_peer_t *peer,
-			 unsigned int tid, int seq_num);
+			 unsigned int tid, uint16_t seq_num);
 
 static inline void xor_block(uint8_t *b, const uint8_t *a, qdf_size_t len)
 {

+ 9 - 3
core/dp/txrx/ol_rx_reorder.c

@@ -607,6 +607,11 @@ ol_rx_flush_handler(ol_txrx_pdev_handle pdev,
 	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
 	htt_pdev_handle htt_pdev = pdev->htt_pdev;
 
+	if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+		ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+		return;
+	}
+
 	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
 	if (peer)
 		vdev = peer->vdev;
@@ -649,8 +654,8 @@ void
 ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev,
 		     uint16_t peer_id,
 		     uint8_t tid,
-		     int seq_num_start,
-		     int seq_num_end, uint8_t pn_ie_cnt, uint8_t *pn_ie)
+		     uint16_t seq_num_start,
+		     uint16_t seq_num_end, uint8_t pn_ie_cnt, uint8_t *pn_ie)
 {
 	struct ol_txrx_vdev_t *vdev = NULL;
 	void *rx_desc;
@@ -660,7 +665,8 @@ ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev,
 	qdf_nbuf_t head_msdu = NULL;
 	qdf_nbuf_t tail_msdu = NULL;
 	htt_pdev_handle htt_pdev = pdev->htt_pdev;
-	int seq_num, i = 0;
+	uint16_t seq_num;
+	int i = 0;
 
 	peer = ol_txrx_peer_find_by_id(pdev, peer_id);