mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 00:41:17 +00:00
61 lines
1.6 KiB
Diff
61 lines
1.6 KiB
Diff
|
From: Ben Greear <greearb@candelatech.com>
|
||
|
Date: Fri, 1 Apr 2016 14:12:09 -0700
|
||
|
Subject: [PATCH] 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: Ben Greear <greearb@candelatech.com>
|
||
|
---
|
||
|
|
||
|
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||
|
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||
|
@@ -773,6 +773,7 @@ static void ath10k_peer_cleanup(struct a
|
||
|
{
|
||
|
struct ath10k_peer *peer, *tmp;
|
||
|
int peer_id;
|
||
|
+ int i;
|
||
|
|
||
|
lockdep_assert_held(&ar->conf_mutex);
|
||
|
|
||
|
@@ -789,6 +790,17 @@ static void ath10k_peer_cleanup(struct a
|
||
|
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);
|
||
|
kfree(peer);
|
||
|
ar->num_peers--;
|
||
|
@@ -799,6 +811,7 @@ static void ath10k_peer_cleanup(struct a
|
||
|
static void ath10k_peer_cleanup_all(struct ath10k *ar)
|
||
|
{
|
||
|
struct ath10k_peer *peer, *tmp;
|
||
|
+ int i;
|
||
|
|
||
|
lockdep_assert_held(&ar->conf_mutex);
|
||
|
|
||
|
@@ -807,6 +820,10 @@ static void ath10k_peer_cleanup_all(stru
|
||
|
list_del(&peer->list);
|
||
|
kfree(peer);
|
||
|
}
|
||
|
+
|
||
|
+ for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
|
||
|
+ ar->peer_map[i] = NULL;
|
||
|
+
|
||
|
spin_unlock_bh(&ar->data_lock);
|
||
|
|
||
|
ar->num_peers = 0;
|