mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 21:54:34 -04:00
qcacmn: Fix issues leading to use-after-free
1. After mem_free() is done for a vdev without peers, set it to NULL so that later check can catch it.If not, it could be used to increment stats. 2. After a bss peer is freed, mark it as NULL so that it is not used again to update stats. Change-Id: I82e73c29c1409aac1af735ab849e8b07d387acf2
This commit is contained in:
parent
0e95ca191b
commit
4a59d8de1c
1 changed files with 18 additions and 6 deletions
|
|
@ -3802,6 +3802,7 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
struct dp_peer *tmppeer;
|
||||
int found = 0;
|
||||
uint16_t peer_id;
|
||||
uint16_t vdev_id;
|
||||
|
||||
/*
|
||||
* Hold the lock all the way from checking if the peer ref count
|
||||
|
|
@ -3819,6 +3820,7 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
peer, qdf_atomic_read(&peer->ref_cnt));
|
||||
if (qdf_atomic_dec_and_test(&peer->ref_cnt)) {
|
||||
peer_id = peer->peer_ids[0];
|
||||
vdev_id = vdev->vdev_id;
|
||||
|
||||
/*
|
||||
* Make sure that the reference to the peer in
|
||||
|
|
@ -3875,9 +3877,9 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
" - its last peer is done"),
|
||||
vdev, vdev->mac_addr.raw);
|
||||
/* all peers are gone, go ahead and delete it */
|
||||
dp_tx_flow_pool_unmap_handler(pdev, vdev->vdev_id,
|
||||
dp_tx_flow_pool_unmap_handler(pdev, vdev_id,
|
||||
FLOW_TYPE_VDEV,
|
||||
vdev->vdev_id);
|
||||
vdev_id);
|
||||
dp_tx_vdev_detach(vdev);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
|
|
@ -3885,6 +3887,7 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
vdev, vdev->mac_addr.raw);
|
||||
|
||||
qdf_mem_free(vdev);
|
||||
vdev = NULL;
|
||||
if (vdev_delete_cb)
|
||||
vdev_delete_cb(vdev_delete_context);
|
||||
}
|
||||
|
|
@ -3892,21 +3895,30 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
|
||||
}
|
||||
|
||||
if (vdev) {
|
||||
if (vdev->vap_bss_peer == peer) {
|
||||
vdev->vap_bss_peer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (soc->cdp_soc.ol_ops->peer_unref_delete) {
|
||||
soc->cdp_soc.ol_ops->peer_unref_delete(pdev->osif_pdev,
|
||||
vdev->vdev_id, peer->mac_addr.raw);
|
||||
vdev_id, peer->mac_addr.raw);
|
||||
}
|
||||
|
||||
if (!vdev || !vdev->vap_bss_peer) {
|
||||
goto free_peer;
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
qdf_mempool_free(soc->osdev, soc->mempool_ol_ath_peer, peer);
|
||||
#else
|
||||
if (!vdev || !vdev->vap_bss_peer)
|
||||
goto free_peer;
|
||||
|
||||
bss_peer = vdev->vap_bss_peer;
|
||||
DP_UPDATE_STATS(bss_peer, peer);
|
||||
|
||||
free_peer:
|
||||
qdf_mem_free(peer);
|
||||
|
||||
#endif
|
||||
} else {
|
||||
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
|
||||
|
|
|
|||
Loading…
Reference in a new issue