diff options
Diffstat (limited to 'package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch')
-rw-r--r-- | package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch b/package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch new file mode 100644 index 0000000000..2979b4b57e --- /dev/null +++ b/package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch @@ -0,0 +1,60 @@ +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; |