From: Ben Greear <[email protected]>

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 <[email protected]>
---
 drivers/net/wireless/ath/ath10k/mac.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 8783119..5e5cc9c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -794,6 +794,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 
vdev_id)
 {
        struct ath10k_peer *peer, *tmp;
        int peer_id;
+       int i;
 
        lockdep_assert_held(&ar->conf_mutex);
 
@@ -812,6 +813,17 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 
vdev_id)
                        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--;
@@ -840,6 +852,7 @@ void ath10k_dump_peer_info(struct ath10k *ar)
 static void ath10k_peer_cleanup_all(struct ath10k *ar)
 {
        struct ath10k_peer *peer, *tmp;
+       int i;
 
        lockdep_assert_held(&ar->conf_mutex);
 
@@ -850,6 +863,10 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
                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;
-- 
2.4.3


_______________________________________________
ath10k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath10k

Reply via email to