wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/683-ath12k-Debug-prints-to-prevent-buffer-overflow.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

86 lines
2.7 KiB
Diff

From 5d42d095c5a898bf670f0271053fee4d9be0827d Mon Sep 17 00:00:00 2001
From: Manish Dharanenthiran <quic_mdharane@quicinc.com>
Date: Mon, 19 Dec 2022 14:24:55 +0530
Subject: [PATCH] ath12k: Add warning to detect buffer overflow
During Mesh 4 node testing, ath12k receives
SKB with header length greater than the MAX
native wifi header length. Because of which,
buffer overflow happens during undecap wifi.
To prevent overflow, added warning before
decap and stopped processing the SKB. Also,
dumped the msdu data for debugging purpose.
Signed-off-by: Manish Dharanenthiran <quic_mdharane@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 51 +++++++++++++++++++++++--
1 file changed, 48 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2940,6 +2940,31 @@ static void ath12k_dp_rx_deliver_msdu(st
}
}
+static bool ath12k_dp_rx_check_max_nwifi_hdr_len(struct ath12k_base *ab,
+ struct hal_rx_desc *rx_desc,
+ struct sk_buff *msdu)
+{
+ u8 decap_type;
+ struct ieee80211_hdr *hdr;
+ u32 hdr_len;
+
+ decap_type = ath12k_dp_rx_h_decap_type(ab, rx_desc);
+ if (decap_type == DP_RX_DECAP_TYPE_NATIVE_WIFI) {
+ hdr = (struct ieee80211_hdr *)msdu->data;
+ hdr_len = ieee80211_hdrlen(hdr->frame_control);
+ if (unlikely(hdr_len > DP_MAX_NWIFI_HDR_LEN)) {
+ ab->soc_stats.invalid_rbm++;
+ ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "msdu_data",
+ msdu->data, msdu->len);
+ ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "rx_desc",
+ rx_desc, sizeof(*rx_desc));
+ return true;
+ }
+ }
+
+ return false;
+}
+
static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
struct sk_buff *msdu,
struct sk_buff_head *msdu_list,
@@ -2999,6 +3024,11 @@ static int ath12k_dp_rx_process_msdu(str
}
}
+ if (ath12k_dp_rx_check_max_nwifi_hdr_len(ab, rx_desc, msdu)) {
+ ret = -EINVAL;
+ goto free_out;
+ }
+
ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status, fast_rx);
if (*fast_rx)
return 0;
@@ -4066,6 +4096,9 @@ static int ath12k_dp_rx_h_null_q_desc(st
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
}
+ if (ath12k_dp_rx_check_max_nwifi_hdr_len(ab, desc, msdu))
+ return -EINVAL;
+
ath12k_dp_rx_h_ppdu(ar, desc, status);
fast_rx = false;
ath12k_dp_rx_h_mpdu(ar, msdu, desc, status, &fast_rx);
@@ -4194,6 +4227,9 @@ static bool ath12k_dp_rx_h_4addr_null_fr
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
+ if (ath12k_dp_rx_check_max_nwifi_hdr_len(ab, rx_desc, msdu))
+ return true;
+
ath12k_dp_rx_h_ppdu(ar, rx_desc, status);
ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, status, &fast_rx);