Commit 6d68f790 authored by Ben Greear's avatar Ben Greear Committed by Kalle Valo

ath10k: ensure peer_map references are cleaned up

While debugging OS crashes due to firmware crashes, I enabled
kasan, and it noticed that peer objects were being used-after-freed.

Looks like there are two places we could be leaving stale references
in the peer-map, so clean that up.
Signed-off-by: default avatarBen Greear <greearb@candelatech.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent de0170be
...@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) ...@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
{ {
struct ath10k_peer *peer, *tmp; struct ath10k_peer *peer, *tmp;
int peer_id; int peer_id;
int i;
lockdep_assert_held(&ar->conf_mutex); lockdep_assert_held(&ar->conf_mutex);
...@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) ...@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
ar->peer_map[peer_id] = NULL; ar->peer_map[peer_id] = NULL;
} }
/* Double check that peer is properly un-referenced from
* the peer_map
*/
for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
if (ar->peer_map[i] == peer) {
ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n",
peer->addr, peer, i);
ar->peer_map[i] = NULL;
}
}
list_del(&peer->list); list_del(&peer->list);
kfree(peer); kfree(peer);
ar->num_peers--; ar->num_peers--;
...@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) ...@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
static void ath10k_peer_cleanup_all(struct ath10k *ar) static void ath10k_peer_cleanup_all(struct ath10k *ar)
{ {
struct ath10k_peer *peer, *tmp; struct ath10k_peer *peer, *tmp;
int i;
lockdep_assert_held(&ar->conf_mutex); lockdep_assert_held(&ar->conf_mutex);
...@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar) ...@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
list_del(&peer->list); list_del(&peer->list);
kfree(peer); kfree(peer);
} }
for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
ar->peer_map[i] = NULL;
spin_unlock_bh(&ar->data_lock); spin_unlock_bh(&ar->data_lock);
ar->num_peers = 0; ar->num_peers = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment