ソースを参照

qcacld-3.0: Fix NULL pointer dereferencing of vdev during peer deletion

During peer deletion, ol_txrx_is_peer_eligible_for_deletion() is
called to check if peer is eligible for deletion. Inside function,
vdev is dereferenced to extract pdev but due to race conditon peer
may get freed from the list and this may lead to NULL pointer
derefencing of vdev.

Avoid dereferencing of vdev and pass pdev itself as an argument to
ol_txrx_is_peer_eligible_for_deletion()

Change-Id: I743e2e2c83c3e07e5d5ec4fde7fc3b098766ca96
CRs-Fixed: 2252243
Alok Kumar 6 年 前
コミット
4d87ff204f
3 ファイル変更7 行追加8 行削除
  1. 3 6
      core/dp/txrx/ol_txrx.c
  2. 3 1
      core/dp/txrx/ol_txrx.h
  3. 1 1
      core/dp/txrx/ol_txrx_peer_find.c

+ 3 - 6
core/dp/txrx/ol_txrx.c

@@ -3461,16 +3461,13 @@ static inline void ol_txrx_peer_free_tids(ol_txrx_peer_handle peer)
 	}
 }
 
-bool ol_txrx_is_peer_eligible_for_deletion(ol_txrx_peer_handle peer)
+bool ol_txrx_is_peer_eligible_for_deletion(ol_txrx_peer_handle peer,
+					   struct ol_txrx_pdev_t *pdev)
 {
-	struct ol_txrx_vdev_t *vdev;
-	struct ol_txrx_pdev_t *pdev;
 	bool peerdel = true;
 	u_int16_t peer_id;
 	int i;
 
-	vdev = peer->vdev;
-	pdev = vdev->pdev;
 	for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) {
 		peer_id = peer->peer_ids[i];
 
@@ -3689,7 +3686,7 @@ int ol_txrx_peer_release_ref(ol_txrx_peer_handle peer,
 		ol_txrx_dump_peer_access_list(peer);
 
 		qdf_spin_lock_bh(&pdev->peer_map_unmap_lock);
-		if (ol_txrx_is_peer_eligible_for_deletion(peer)) {
+		if (ol_txrx_is_peer_eligible_for_deletion(peer, pdev)) {
 			qdf_mem_free(peer);
 		} else {
 			/*

+ 3 - 1
core/dp/txrx/ol_txrx.h

@@ -41,10 +41,12 @@ int  ol_txrx_peer_release_ref(ol_txrx_peer_handle peer,
 			      enum peer_debug_id_type dbg_id);
 /* ol_txrx_is_peer_eligible_for_deletion() - check if peer to be deleted
  * @peer: peer handler
+ * @pdev: pointer to pdev
  *
  * Return: true if eligible for deletion else false
  */
-bool ol_txrx_is_peer_eligible_for_deletion(ol_txrx_peer_handle peer);
+bool ol_txrx_is_peer_eligible_for_deletion(ol_txrx_peer_handle peer,
+					   struct ol_txrx_pdev_t *pdev);
 
 /**
  * ol_tx_desc_pool_size_hl() - allocate tx descriptor pool size for HL systems

+ 1 - 1
core/dp/txrx/ol_txrx_peer_find.c

@@ -637,7 +637,7 @@ void ol_rx_peer_unmap_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id)
 							del_peer_id_ref_cnt);
 
 		peer = pdev->peer_id_to_obj_map[peer_id].peer_ref;
-		if (peer && ol_txrx_is_peer_eligible_for_deletion(peer)) {
+		if (peer && ol_txrx_is_peer_eligible_for_deletion(peer, pdev)) {
 			TAILQ_FOREACH_SAFE(stale_peer,
 					   &pdev->roam_stale_peer_list,
 					   next_stale_entry,