From 83b29e014f063d23bd6859a37ce4ff424a080ab8 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Tue, 6 Jul 2021 00:07:39 +0800 Subject: [PATCH] ath11k: fix for peer memory corruption --- ...th11k-fix-for-peer-memory-corruption.patch | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k/133-ath11k-fix-for-peer-memory-corruption.patch diff --git a/package/kernel/mac80211/patches/ath11k/133-ath11k-fix-for-peer-memory-corruption.patch b/package/kernel/mac80211/patches/ath11k/133-ath11k-fix-for-peer-memory-corruption.patch new file mode 100644 index 000000000..10331849b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/133-ath11k-fix-for-peer-memory-corruption.patch @@ -0,0 +1,103 @@ +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1492,11 +1492,9 @@ struct htt_ppdu_stats_info *ath11k_dp_ht + { + struct htt_ppdu_stats_info *ppdu_info; + +- spin_lock_bh(&ar->data_lock); + if (!list_empty(&ar->ppdu_stats_info)) { + list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { + if (ppdu_info->ppdu_id == ppdu_id) { +- spin_unlock_bh(&ar->data_lock); + return ppdu_info; + } + } +@@ -1510,16 +1508,13 @@ struct htt_ppdu_stats_info *ath11k_dp_ht + kfree(ppdu_info); + } + } +- spin_unlock_bh(&ar->data_lock); + + ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); + if (!ppdu_info) + return NULL; + +- spin_lock_bh(&ar->data_lock); + list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); + ar->ppdu_stat_list_depth++; +- spin_unlock_bh(&ar->data_lock); + + return ppdu_info; + } +@@ -1549,8 +1544,10 @@ static int ath11k_htt_pull_ppdu_stats(st + if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar)) + trace_ath11k_htt_ppdu_stats(ar, skb->data, len); + ++ spin_lock_bh(&ar->data_lock); + ppdu_info = ath11k_dp_htt_get_ppdu_desc(ar, ppdu_id); + if (!ppdu_info) { ++ spin_unlock_bh(&ar->data_lock); + ret = -EINVAL; + goto exit; + } +@@ -1560,10 +1557,12 @@ static int ath11k_htt_pull_ppdu_stats(st + ath11k_htt_tlv_ppdu_stats_parse, + (void *)ppdu_info); + if (ret) { ++ spin_unlock_bh(&ar->data_lock); + ath11k_warn(ab, "Failed to parse tlv %d\n", ret); + goto exit; + } + ++ spin_unlock_bh(&ar->data_lock); + exit: + rcu_read_unlock(); + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2451,22 +2451,28 @@ static int ath11k_clear_peer_keys(struct + int ret; + int i; + u32 flags = 0; ++ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; + + lockdep_assert_held(&ar->conf_mutex); + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find(ab, arvif->vdev_id, addr); +- spin_unlock_bh(&ab->base_lock); +- +- if (!peer) ++ if (!peer) { ++ spin_unlock_bh(&ab->base_lock); + return -ENOENT; ++ } ++ for (i = 0; i < ARRAY_SIZE(keys); i++) { ++ keys[i]= peer->keys[i]; ++ peer->keys[i]= NULL; ++ } ++ spin_unlock_bh(&ab->base_lock); + +- for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { +- if (!peer->keys[i]) ++ for (i = 0; i < ARRAY_SIZE(keys); i++) { ++ if (!keys[i]) + continue; + + /* key flags are not required to delete the key */ +- ret = ath11k_install_key(arvif, peer->keys[i], ++ ret = ath11k_install_key(arvif, keys[i], + DISABLE_KEY, addr, flags); + if (ret < 0 && first_errno == 0) + first_errno = ret; +@@ -2474,10 +2480,6 @@ static int ath11k_clear_peer_keys(struct + if (ret < 0) + ath11k_warn(ab, "failed to remove peer key %d: %d\n", + i, ret); +- +- spin_lock_bh(&ab->base_lock); +- peer->keys[i] = NULL; +- spin_unlock_bh(&ab->base_lock); + } + + return first_errno;