From 8cb4be3fd31fff86a0e396c0c59ea700bf66411b Mon Sep 17 00:00:00 2001 From: sheenam monga Date: Fri, 3 May 2019 17:11:11 +0530 Subject: [PATCH] qcacld-3.0: Fix bss peer use after free in pmo wlan_vdev_get_bsspeer() return bss peer without taking the ref count of the peer and thus if peer is deleted after wlan_vdev_get_bsspeer() returns a valid peer, the caller will have stale entry of the peer. Stale entry of peer can lead to Assert. Use wlan_objmgr_vdev_try_get_bsspeer API for pmo to get the BSS peer which increment the refcount if peer is valid. With this the peer won't be deleted till the caller release the ref count of the peer. Change-Id: I0901164132c497d78c9dc603539b045e5ce0f152 CRs-Fixed: 2446618 --- components/pmo/core/src/wlan_pmo_main.c | 5 +++-- components/pmo/core/src/wlan_pmo_ns.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/components/pmo/core/src/wlan_pmo_main.c b/components/pmo/core/src/wlan_pmo_main.c index b34521894f0b..4907f580172f 100644 --- a/components/pmo/core/src/wlan_pmo_main.c +++ b/components/pmo/core/src/wlan_pmo_main.c @@ -255,17 +255,18 @@ QDF_STATUS pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_INVAL; } - peer = wlan_vdev_get_bsspeer(vdev); + peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_PMO_ID); if (!peer) { pmo_err("peer is null"); return QDF_STATUS_E_INVAL; } - wlan_peer_obj_lock(peer); qdf_mem_copy(bss_peer_mac_address->bytes, wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_PMO_ID); + return QDF_STATUS_SUCCESS; } diff --git a/components/pmo/core/src/wlan_pmo_ns.c b/components/pmo/core/src/wlan_pmo_ns.c index 5160e3d2f226..8770167cf576 100644 --- a/components/pmo/core/src/wlan_pmo_ns.c +++ b/components/pmo/core/src/wlan_pmo_ns.c @@ -94,7 +94,7 @@ static QDF_STATUS pmo_core_cache_ns_in_vdev_priv( /* set number of ns offload address count */ request.num_ns_offload_count = ns_req->count; - peer = wlan_vdev_get_bsspeer(vdev); + peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_PMO_ID); if (!peer) { pmo_err("peer is null"); status = QDF_STATUS_E_INVAL; @@ -107,6 +107,7 @@ static QDF_STATUS pmo_core_cache_ns_in_vdev_priv( qdf_mem_copy(&request.bssid, wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + wlan_objmgr_peer_release_ref(peer, WLAN_PMO_ID); /* cache ns request */ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock); qdf_mem_copy(&vdev_ctx->vdev_ns_req, &request,