ath11k: memory leak patches (#7546)

This commit is contained in:
ntlf9t 2021-07-28 10:12:15 +08:00 committed by GitHub
parent 9f569564f3
commit fde8a69c47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 272 additions and 0 deletions

View File

@ -0,0 +1,47 @@
From c8bcd82a4efd053cdd5ce515a8b0003011a5f756 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Wed, 16 Jun 2021 12:54:10 -0700
Subject: [PATCH] ath11k: Avoid memcpy() over-reading of he_cap
In preparation for FORTIFY_SOURCE performing compile-time and run-time
field bounds checking for memcpy(), memmove(), and memset(), avoid
intentionally writing across neighboring array fields.
Since peer_he_cap_{mac,phy}info and he_cap_elem.{mac,phy}_cap_info are not
the same sizes, memcpy() was reading beyond field boundaries. Instead,
correctly cap the copy length and pad out any difference in size
(peer_he_cap_macinfo is 8 bytes whereas mac_cap_info is 6, and
peer_he_cap_phyinfo is 12 bytes whereas phy_cap_info is 11).
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210616195410.1232119-1-keescook@chromium.org
---
drivers/net/wireless/ath/ath11k/mac.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index eb52332dbe3f13..e9b3689331ec2a 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1314,10 +1314,16 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
arg->he_flag = true;
- memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info,
- sizeof(arg->peer_he_cap_macinfo));
- memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info,
- sizeof(arg->peer_he_cap_phyinfo));
+ memcpy_and_pad(&arg->peer_he_cap_macinfo,
+ sizeof(arg->peer_he_cap_macinfo),
+ he_cap->he_cap_elem.mac_cap_info,
+ sizeof(he_cap->he_cap_elem.mac_cap_info),
+ 0);
+ memcpy_and_pad(&arg->peer_he_cap_phyinfo,
+ sizeof(arg->peer_he_cap_phyinfo),
+ he_cap->he_cap_elem.phy_cap_info,
+ sizeof(he_cap->he_cap_elem.phy_cap_info),
+ 0);
arg->peer_he_ops = vif->bss_conf.he_oper.params;
/* the top most byte is used to indicate BSS color info */

View File

@ -0,0 +1,31 @@
From fb359946c3effad77a3ac8ebc943ea5cac22d335 Mon Sep 17 00:00:00 2001
From: Bhaumik Bhatt <bbhatt@codeaurora.org>
Date: Thu, 6 May 2021 12:51:43 -0700
Subject: [PATCH] ath11k: set register access length for MHI driver
MHI driver requires register space length to add range checks and
prevent memory region accesses outside of that for MMIO space.
Set it before registering the MHI controller.
Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
Reviewed-by: Hemant Kumar <hemantk@codeaurora.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Acked-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1620330705-40192-5-git-send-email-bbhatt@codeaurora.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
drivers/net/wireless/ath/ath11k/mhi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index 27b394d115e26a..e097ae52e25733 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -330,6 +330,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
mhi_ctrl->cntrl_dev = ab->dev;
mhi_ctrl->fw_image = ab_pci->amss_path;
mhi_ctrl->regs = ab->mem;
+ mhi_ctrl->reg_len = ab->mem_len;
ret = ath11k_mhi_get_msi(ab_pci);
if (ret) {

View File

@ -0,0 +1,34 @@
From 515bda1d1e51c64edf2a384a58801f85a80a3f2d Mon Sep 17 00:00:00 2001
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Date: Sat, 22 May 2021 11:50:54 +0200
Subject: ath11k: Fix an error handling path in
ath11k_core_fetch_board_data_api_n()
All error paths but this one 'goto err' in order to release some
resources.
Fix this.
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/e959eb544f3cb04258507d8e25a6f12eab126bde.1621676864.git.christophe.jaillet@wanadoo.fr
---
drivers/net/wireless/ath/ath11k/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 4a1051418f33a..969bf1a590d99 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -532,7 +532,8 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
if (len < ALIGN(ie_len, 4)) {
ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
ie_id, ie_len, len);
- return -EINVAL;
+ ret = -EINVAL;
+ goto err;
}
switch (ie_id) {
--
cgit 1.2.3-1.el7

View File

@ -0,0 +1,57 @@
From 979ebc54cf13bd1e3eb6e21766d208d5de984fb8 Mon Sep 17 00:00:00 2001
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
Date: Tue, 25 May 2021 15:30:28 +0200
Subject: ath11k: send beacon template after vdev_start/restart during csa
Firmware has added assert if beacon template is received after
vdev_down. Firmware expects beacon template after vdev_start
and before vdev_up. This change is needed to support MBSSID EMA
cases in firmware.
Hence, Change the sequence in ath11k as expected from firmware.
This new change is not causing any issues with older
firmware.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1.r3-00011-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1.r4-00008-QCAHKSWPL_SILICONZ-1
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
[sven@narfation.org: added tested-on/fixes information]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210525133028.2805615-1-sven@narfation.org
---
drivers/net/wireless/ath/ath11k/mac.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 9d0ff150ec30f..eb52332dbe3f1 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5379,11 +5379,6 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
if (WARN_ON(!arvif->is_up))
continue;
- ret = ath11k_mac_setup_bcn_tmpl(arvif);
- if (ret)
- ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
- ret);
-
ret = ath11k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def);
if (ret) {
ath11k_warn(ab, "failed to restart vdev %d: %d\n",
@@ -5391,6 +5386,11 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
continue;
}
+ ret = ath11k_mac_setup_bcn_tmpl(arvif);
+ if (ret)
+ ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
+ ret);
+
ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
arvif->bssid);
if (ret) {
--
cgit 1.2.3-1.el7

View File

@ -0,0 +1,103 @@
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1463,11 +1463,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;
}
}
@@ -1481,16 +1479,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;
}
@@ -1522,8 +1517,10 @@ static int ath11k_htt_pull_ppdu_stats(st
ath11k_htt_ppdu_pktlog_process(ar, (u8 *)skb->data, DP_RX_BUFFER_SIZE);
}
+ 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;
}
@@ -1533,10 +1530,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
@@ -2755,22 +2755,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;
@@ -2778,10 +2784,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;