From 1d83933bbbb28e73e1f1457c208e37861593d5c6 Mon Sep 17 00:00:00 2001 From: sheenam monga Date: Wed, 1 May 2019 15:09:07 +0530 Subject: [PATCH] qcacld-3.0: Fix bss peer use after free in hdd 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 in hdd 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: I9adf79810c7ec02af377f485eee596dd14289b50 CRs-Fixed: 2445716 --- core/hdd/src/wlan_hdd_object_manager.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/core/hdd/src/wlan_hdd_object_manager.c b/core/hdd/src/wlan_hdd_object_manager.c index cc6139fa4ed5..eb481d0afc38 100644 --- a/core/hdd/src/wlan_hdd_object_manager.c +++ b/core/hdd/src/wlan_hdd_object_manager.c @@ -365,26 +365,18 @@ int hdd_objmgr_set_peer_mlme_auth_state(struct wlan_objmgr_vdev *vdev, bool is_authenticated) { struct wlan_objmgr_peer *peer; - QDF_STATUS status; - - wlan_vdev_obj_lock(vdev); - peer = wlan_vdev_get_bsspeer(vdev); - wlan_vdev_obj_unlock(vdev); + peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_OSIF_ID); if (!peer) { hdd_err("peer is null"); - return -EINVAL; } - status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); - if (status != QDF_STATUS_SUCCESS) - return -EINVAL; wlan_peer_obj_lock(peer); wlan_peer_mlme_set_auth_state(peer, is_authenticated); wlan_peer_obj_unlock(peer); - wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); + wlan_objmgr_peer_release_ref(peer, WLAN_OSIF_ID); return 0; } @@ -393,13 +385,9 @@ int hdd_objmgr_set_peer_mlme_state(struct wlan_objmgr_vdev *vdev, { struct wlan_objmgr_peer *peer; - wlan_vdev_obj_lock(vdev); - peer = wlan_vdev_get_bsspeer(vdev); - wlan_vdev_obj_unlock(vdev); - + peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_OSIF_ID); if (!peer) { hdd_err("peer is null"); - return -EINVAL; } @@ -407,6 +395,7 @@ int hdd_objmgr_set_peer_mlme_state(struct wlan_objmgr_vdev *vdev, wlan_peer_mlme_set_state(peer, WLAN_ASSOC_STATE); wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_OSIF_ID); return 0; }