wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/355-ath11k-Fix-invalid-mgmt-rx-frame-length-issue.patch
John Crispin b9b03a6e38 ipq95xx: add Qualcomm wifi-7 support
Signed-off-by: John Crispin <john@phrozen.org>
2023-04-10 14:25:48 +02:00

110 lines
2.9 KiB
Diff

From 0acc603ee1fbbeca1109e695f493179986b18c34 Mon Sep 17 00:00:00 2001
From: Bhagavathi Perumal S <quic_bperumal@quicinc.com>
Date: Wed, 6 Jul 2022 14:42:29 +0530
Subject: [PATCH 2/2] ath11k: Fix invalid mgmt rx frame length issue
The wmi mgmt rx event has multiple arrays of tlvs,
but the common wmi tlv parser won't handle mulitple tlv tags of same type.
So the mulitple array tags of wmi mgmt rx tlv is parsed incorrectly and
the length calculated becomes wrong,
Add seperate tlv parser to handle mulitple arrays for wmi mgmt rx tlv.
This fixes invalid length issue.
Signed-off-by: Bhagavathi Perumal S <quic_bperumal@quicinc.com>
---
drivers/net/wireless/ath/ath11k/wmi.c | 38 ++++++++++++++++++++++++++---------
drivers/net/wireless/ath/ath11k/wmi.h | 6 ++++++
2 files changed, 34 insertions(+), 10 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -6430,28 +6430,48 @@ static int ath11k_pull_vdev_stopped_para
return 0;
}
+static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base *ab,
+ u16 tag, u16 len,
+ const void *ptr, void *data)
+{
+ struct wmi_tlv_mgmt_rx_parse *parse = data;
+
+ switch (tag) {
+ case WMI_TAG_MGMT_RX_HDR:
+ parse->fixed = ptr;
+ break;
+ case WMI_TAG_ARRAY_BYTE:
+ if (!parse->frame_buf_done) {
+ parse->frame_buf = ptr;
+ parse->frame_buf_done = true;
+ }
+ break;
+ }
+ return 0;
+}
+
static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
struct sk_buff *skb,
struct mgmt_rx_event_params *hdr)
{
- const void **tb;
+ struct wmi_tlv_mgmt_rx_parse parse = { };
const struct wmi_mgmt_rx_hdr *ev;
const u8 *frame;
int ret;
- tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
- if (IS_ERR(tb)) {
- ret = PTR_ERR(tb);
- ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
+ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
+ ath11k_wmi_tlv_mgmt_rx_parse,
+ &parse);
+ if (ret) {
+ ath11k_warn(ab, "failed to parse mgmt rx tlv %d\n", ret);
return ret;
}
- ev = tb[WMI_TAG_MGMT_RX_HDR];
- frame = tb[WMI_TAG_ARRAY_BYTE];
+ ev = parse.fixed;
+ frame = parse.frame_buf;
if (!ev || !frame) {
ath11k_warn(ab, "failed to fetch mgmt rx hdr");
- kfree(tb);
return -EPROTO;
}
@@ -6470,7 +6490,6 @@ static int ath11k_pull_mgmt_rx_params_tl
if (skb->len < (frame - skb->data) + hdr->buf_len) {
ath11k_warn(ab, "invalid length in mgmt rx hdr ev");
- kfree(tb);
return -EPROTO;
}
@@ -6482,7 +6501,6 @@ static int ath11k_pull_mgmt_rx_params_tl
ath11k_ce_byte_swap(skb->data, hdr->buf_len);
- kfree(tb);
return 0;
}
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -5169,6 +5169,12 @@ struct wmi_mgmt_rx_hdr {
u32 chan_freq;
} __packed;
+struct wmi_tlv_mgmt_rx_parse {
+ struct wmi_mgmt_rx_hdr *fixed;
+ u8 *frame_buf;
+ bool frame_buf_done;
+};
+
#define MAX_ANTENNA_EIGHT 8
struct wmi_rssi_ctl_ext {