mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
114 lines
4.0 KiB
Diff
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,
|