Browse Source

qcacmn: Retrieve peer from mac based search

Use mac based search to avoid use after free Peer.

Change-Id: Ie6c3e82f3bb95cdf4c6504e95704e821bbd19e24
Ankit Kumar 5 years ago
parent
commit
673a66042b
1 changed files with 53 additions and 13 deletions
  1. 53 13
      dp/wifi3.0/dp_htt.c

+ 53 - 13
dp/wifi3.0/dp_htt.c

@@ -2323,10 +2323,15 @@ static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
 							  ppdu_desc->vdev_id);
 		if (!vdev)
 			return;
+		qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw,
+			     QDF_MAC_ADDR_SIZE);
 	} else {
 		peer = dp_peer_find_by_id(pdev->soc, peer_id);
 		if (!peer)
 			return;
+		ppdu_desc->vdev_id = peer->vdev->vdev_id;
+		qdf_mem_copy(ppdu_user_desc->mac_addr, peer->mac_addr.raw,
+			     QDF_MAC_ADDR_SIZE);
 		dp_peer_unref_del_find_by_id(peer);
 	}
 
@@ -2397,6 +2402,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
 	uint8_t curr_user_index = 0;
 	uint16_t peer_id;
+	struct dp_peer *peer;
 	uint32_t size = CDP_BA_64_BIT_MAP_SIZE_DWORDS;
 
 	ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
@@ -2406,12 +2412,17 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
 	peer_id =
 	HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	if (!dp_peer_find_by_id_valid(pdev->soc, peer_id))
+	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	if (!peer)
 		return;
 
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
+	ppdu_desc->vdev_id = peer->vdev->vdev_id;
+	qdf_mem_copy(ppdu_user_desc->mac_addr,
+		     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+	dp_peer_unref_del_find_by_id(peer);
 	ppdu_user_desc->peer_id = peer_id;
 
 	ppdu_user_desc->start_seq = dp_stats_buf->start_seq;
@@ -2444,6 +2455,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
 	uint8_t curr_user_index = 0;
 	uint16_t peer_id;
+	struct dp_peer *peer;
 	uint32_t size = CDP_BA_256_BIT_MAP_SIZE_DWORDS;
 
 	ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
@@ -2453,12 +2465,16 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
 	peer_id =
 	HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	if (!dp_peer_find_by_id_valid(pdev->soc, peer_id))
+	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	if (!peer)
 		return;
-
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
+	ppdu_desc->vdev_id = peer->vdev->vdev_id;
+	qdf_mem_copy(ppdu_user_desc->mac_addr,
+		     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+	dp_peer_unref_del_find_by_id(peer);
 	ppdu_user_desc->peer_id = peer_id;
 
 	ppdu_user_desc->start_seq = dp_stats_buf->start_seq;
@@ -2485,6 +2501,7 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
 		struct ppdu_info *ppdu_info)
 {
 	uint16_t peer_id;
+	struct dp_peer *peer;
 	struct cdp_tx_completion_ppdu *ppdu_desc;
 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
 	uint8_t curr_user_index = 0;
@@ -2498,13 +2515,18 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
 	peer_id =
 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	if (!dp_peer_find_by_id_valid(pdev->soc, peer_id))
+	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	if (!peer)
 		return;
 
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
-	ppdu_user_desc->peer_id = peer_id;
 	ppdu_desc->last_usr_index = curr_user_index;
+	ppdu_desc->vdev_id = peer->vdev->vdev_id;
+	qdf_mem_copy(ppdu_user_desc->mac_addr,
+		     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+	dp_peer_unref_del_find_by_id(peer);
+	ppdu_user_desc->peer_id = peer_id;
 
 	ppdu_user_desc->completion_status =
 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_COMPLETION_STATUS_GET(
@@ -2617,6 +2639,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
 	struct cdp_tx_completion_ppdu *ppdu_desc;
 	uint8_t curr_user_index = 0;
 	uint16_t peer_id;
+	struct dp_peer *peer;
 
 	ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
 
@@ -2625,12 +2648,17 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
 	peer_id =
 	HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	if (!dp_peer_find_by_id_valid(pdev->soc, peer_id))
+	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	if (!peer)
 		return;
 
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
+	ppdu_desc->vdev_id = peer->vdev->vdev_id;
+	qdf_mem_copy(ppdu_user_desc->mac_addr,
+		     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+	dp_peer_unref_del_find_by_id(peer);
 	ppdu_user_desc->peer_id = peer_id;
 
 	ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no;
@@ -2658,6 +2686,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
 	struct cdp_tx_completion_ppdu *ppdu_desc;
 	uint8_t curr_user_index = 0;
 	uint16_t peer_id;
+	struct dp_peer *peer;
 
 	ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
 
@@ -2666,12 +2695,17 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
 	peer_id =
 	HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	if (!dp_peer_find_by_id_valid(pdev->soc, peer_id))
+	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	if (!peer)
 		return;
 
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
+	ppdu_desc->vdev_id = peer->vdev->vdev_id;
+	qdf_mem_copy(ppdu_user_desc->mac_addr,
+		     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+	dp_peer_unref_del_find_by_id(peer);
 	ppdu_user_desc->peer_id = peer_id;
 
 	ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no;
@@ -2694,6 +2728,7 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
 		struct ppdu_info *ppdu_info)
 {
 	uint16_t peer_id;
+	struct dp_peer *peer;
 	struct cdp_tx_completion_ppdu *ppdu_desc;
 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
 	uint8_t curr_user_index = 0;
@@ -2704,12 +2739,16 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
 	peer_id =
 	HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	if (!dp_peer_find_by_id_valid(pdev->soc, peer_id))
+	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	if (!peer)
 		return;
-
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
+	ppdu_desc->vdev_id = peer->vdev->vdev_id;
+	qdf_mem_copy(ppdu_user_desc->mac_addr,
+		     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+	dp_peer_unref_del_find_by_id(peer);
 	ppdu_user_desc->peer_id = peer_id;
 
 	tag_buf++;
@@ -3117,8 +3156,9 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
 		ppdu_desc->num_mpdu += ppdu_desc->user[i].num_mpdu;
 		ppdu_desc->num_msdu += ppdu_desc->user[i].num_msdu;
 
-		peer = dp_peer_find_by_id(pdev->soc,
-					  ppdu_desc->user[i].peer_id);
+		peer = dp_peer_find_hash_find(pdev->soc,
+					      ppdu_desc->user[i].mac_addr,
+					      0, ppdu_desc->vdev_id);
 		/**
 		 * This check is to make sure peer is not deleted
 		 * after processing the TLVs.
@@ -3145,7 +3185,7 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
 		       (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV)) &&
 		     (ppdu_desc->user[i].completion_status ==
 		      HTT_PPDU_STATS_USER_STATUS_OK))) {
-			dp_peer_unref_del_find_by_id(peer);
+			dp_peer_unref_delete(peer);
 			continue;
 		}
 
@@ -3166,7 +3206,7 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
 			dp_tx_rate_stats_update(peer, &ppdu_desc->user[i]);
 		}
 
-		dp_peer_unref_del_find_by_id(peer);
+		dp_peer_unref_delete(peer);
 		tlv_bitmap_expected = tlv_bitmap_default;
 	}
 }