wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/784-01-wifi-ath12k-fix-array-out-of-bound-in-undecap-native.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

114 lines
4.0 KiB
Diff

From b5d7239d873fa775420d6f36c9703999a95c032c Mon Sep 17 00:00:00 2001
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Date: Wed, 21 Jun 2023 14:55:11 +0530
Subject: [PATCH 1/2] wifi: ath12k: fix array out of bound in undecap native
wifi frame path
Randomly in undecap native wifi path, msdu header frame control has QoS data.
which is wrong because QoS not present in native wifi frame. so when we take
a copy of native wifi header, the destination array get out of bound access
due to the addition of unexpected QoS length from source. Fix this issue by
reset the QoS length, Order length and recalculate the header length then
proceed the undecap procedure without the local array and remove the unused
define.
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 33 ++++++++++++++-----------
drivers/net/wireless/ath/ath12k/dp_rx.h | 3 ---
2 files changed, 18 insertions(+), 18 deletions(-)
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2407,23 +2407,27 @@ static void ath12k_dp_rx_h_undecap_nwifi
{
struct ath12k_base *ab = ar->ab;
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
- u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN];
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr hdr;
size_t hdr_len;
int expand_by = 0;
u8 *crypto_hdr;
- u16 qos_ctl = 0;
+ u16 qos_ctl;
/* pull decapped header */
- hdr = (struct ieee80211_hdr *)msdu->data;
- hdr_len = ieee80211_hdrlen(hdr->frame_control);
+ hdr = *((struct ieee80211_hdr *)msdu->data);
+ hdr_len = ieee80211_hdrlen(hdr.frame_control);
skb_pull(msdu, hdr_len);
- /* Rebuild qos header */
- hdr->frame_control |= __cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
+ /* FIXME Nwifi header should not exceed struct ieee80211_hdr size (30) */
+ WARN_ON_ONCE(hdr_len > sizeof(hdr));
- /* Reset the order bit as the HT_Control header is stripped */
- hdr->frame_control &= ~(__cpu_to_le16(IEEE80211_FCTL_ORDER));
+ /*
+ * Reset the QoS bit since it is nwifi frame
+ * Reset the order bit as the HT_Control header is stripped
+ */
+ hdr.frame_control &= ~(__cpu_to_le16(IEEE80211_STYPE_QOS_DATA) |
+ __cpu_to_le16(IEEE80211_FCTL_ORDER));
+ hdr_len = ieee80211_hdrlen(hdr.frame_control);
qos_ctl = rxcb->tid;
@@ -2432,9 +2436,6 @@ static void ath12k_dp_rx_h_undecap_nwifi
/* TODO Add other QoS ctl fields when required */
- /* copy decap header before overwriting for reuse below */
- memcpy(decap_hdr, (uint8_t *)hdr, hdr_len);
-
/* Rebuild crypto header for mac80211 use */
if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
if (skb_headroom(msdu) < ath12k_dp_rx_crypto_param_len(ar, enctype)) {
@@ -2453,16 +2454,21 @@ static void ath12k_dp_rx_h_undecap_nwifi
if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC)))
return;
}
+
+ /* Rebuild qos header */
memcpy(skb_push(msdu,
IEEE80211_QOS_CTL_LEN), &qos_ctl,
IEEE80211_QOS_CTL_LEN);
+ hdr.frame_control |= __cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
+
if (skb_headroom(msdu) < hdr_len) {
expand_by = hdr_len - skb_headroom(msdu);
if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC)))
return;
}
- memcpy(skb_push(msdu, hdr_len), decap_hdr, hdr_len);
+
+ memcpy(skb_push(msdu, hdr_len), &hdr, hdr_len);
}
static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu,
@@ -3164,7 +3170,7 @@ static bool ath12k_dp_rx_check_max_nwifi
hdr = (struct ieee80211_hdr *)msdu->data;
hdr_len = ieee80211_hdrlen(hdr->frame_control);
- if (unlikely(hdr_len > DP_MAX_NWIFI_HDR_LEN)) {
+ if (unlikely(hdr_len > sizeof(*hdr))) {
ab->soc_stats.invalid_rbm++;
ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "msdu_data",
msdu->data, msdu->len);
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -10,9 +10,6 @@
#include "rx_desc.h"
#include "debug.h"
-#define DP_MAX_NWIFI_HDR_LEN 30
-
-
/* different supported pkt types for routing */
enum ath12k_routing_pkt_type {
ATH12K_PKT_TYPE_ARP_IPV4,