From 4d87ff204f4edfd6a8c8c6d25f1ceed70a52b20d Mon Sep 17 00:00:00 2001 From: Alok Kumar Date: Fri, 1 Jun 2018 17:15:57 +0530 Subject: [PATCH] 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 --- core/dp/txrx/ol_txrx.c | 9 +++------ core/dp/txrx/ol_txrx.h | 4 +++- core/dp/txrx/ol_txrx_peer_find.c | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 47089b9d4d76..81d9a79505f5 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/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 { /* diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h index d7a92837434b..609279d2ccf8 100644 --- a/core/dp/txrx/ol_txrx.h +++ b/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 diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c index 522df0f9efd4..392cfd518b3f 100644 --- a/core/dp/txrx/ol_txrx_peer_find.c +++ b/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,