summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimanshu Agarwal <himanaga@qti.qualcomm.com>2015-12-10 12:52:38 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2015-12-16 12:38:42 +0530
commit8ecaa7bd0d402652a896c02e516e2db8d866ffdd (patch)
tree37bd58a125074cdbb91960da84d3456e8e8960d0
parentbb00dc469d0c76eeb50925b6674597950a1cd6ef (diff)
qcacld-2.0: Avoid double free of vdev
Due to a race condition, vdev is getting deleted in ol_txrx_vdev_detach and after that in ol_txrx_peer_unref_delete, as vdev->delete.pending is not equal to 0 as it is some garbage value, vdev is getting deleted again causing crash. This fix release the lock after checking vdev->delete.pending so that before vdev gets deleted in ol_txrx_vdev_detach, this check has been made and as vdev->delete.pending is 0, it will not delete the vdev in ol_txrx_peer_unref_delete and so vdev will be deleted only once. Change-Id: I4a7362b0e226c66ccb7c72243276d77e8df60b20 CRs-Fixed: 949397
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c
index 74369051e810..48c328ff111d 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx.c
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c
@@ -1693,18 +1693,19 @@ ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
/* check whether the parent vdev has no peers left */
if (TAILQ_EMPTY(&vdev->peer_list)) {
/*
- * Now that there are no references to the peer, we can
- * release the peer reference lock.
- */
- adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
- /*
* Check if the parent vdev was waiting for its peers to be
* deleted, in order for it to be deleted too.
*/
- if (vdev->delete.pending) {
+ if (vdev->delete.pending == 1) {
ol_txrx_vdev_delete_cb vdev_delete_cb = vdev->delete.callback;
void *vdev_delete_context = vdev->delete.context;
+ /*
+ * Now that there are no references to the peer, we can
+ * release the peer reference lock.
+ */
+ adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
+
TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1,
"%s: deleting vdev object %p "
"(%02x:%02x:%02x:%02x:%02x:%02x)"
@@ -1718,6 +1719,8 @@ ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
if (vdev_delete_cb) {
vdev_delete_cb(vdev_delete_context);
}
+ } else {
+ adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
}
} else {
adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);