Răsfoiți Sursa

qcacld-3.0: Fix peer use after free in wma_is_ccmp_pn_replay_attack

In wma_is_ccmp_pn_replay_attack peer is used without taking the ref
count and thus this can lead to peer used after free.

Fix this by taking ref of peer before using the peer in
wma_is_ccmp_pn_replay_attack and release ref once access is done.

Change-Id: Iaa5936a1c7f6f8667a68fcb646eaec4cb3aa5469
CRs-Fixed: 2264434
Abhishek Singh 7 ani în urmă
părinte
comite
38da980436
1 a modificat fișierele cu 9 adăugiri și 6 ștergeri
  1. 9 6
      core/wma/src/wma_mgmt.c

+ 9 - 6
core/wma/src/wma_mgmt.c

@@ -3415,6 +3415,7 @@ wma_is_ccmp_pn_replay_attack(void *cds_ctx, struct ieee80211_frame *wh,
 	uint64_t *last_pn = NULL, new_pn;
 	uint32_t *rmf_pn_replays = NULL;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	bool ret = false;
 
 	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
 	if (!pdev) {
@@ -3429,10 +3430,10 @@ wma_is_ccmp_pn_replay_attack(void *cds_ctx, struct ieee80211_frame *wh,
 	}
 
 	/* Retrieve the peer based on vdev and addr */
-	peer = cdp_peer_find_by_addr_and_vdev(soc, pdev,
-			vdev, wh->i_addr2, &peer_id);
+	peer = cdp_peer_get_ref_by_addr(soc, pdev, wh->i_addr2, &peer_id,
+					PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
 
-	if (NULL == peer) {
+	if (!peer) {
 		WMA_LOGE("%s: Failed to find peer, Not able to validate PN",
 			    __func__);
 		return true;
@@ -3444,7 +3445,7 @@ wma_is_ccmp_pn_replay_attack(void *cds_ctx, struct ieee80211_frame *wh,
 
 	if (!last_pn_valid || !last_pn || !rmf_pn_replays) {
 		WMA_LOGE("%s: PN validation seems not supported", __func__);
-		return false;
+		goto rel_peer_ref;
 	}
 
 	if (*last_pn_valid) {
@@ -3455,14 +3456,16 @@ wma_is_ccmp_pn_replay_attack(void *cds_ctx, struct ieee80211_frame *wh,
 			WMA_LOGE("%s: PN Replay attack detected", __func__);
 			/* per 11W amendment, keeping track of replay attacks */
 			*rmf_pn_replays += 1;
-			return true;
+			ret = true;
 		}
 	} else {
 		*last_pn_valid = 1;
 		*last_pn = new_pn;
 	}
 
-	return false;
+rel_peer_ref:
+	cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
+	return ret;
 }
 
 /**