mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-10 14:07:07 +08:00
119 lines
3.9 KiB
Diff
119 lines
3.9 KiB
Diff
From d3d358efc553de4f9d803c889a2e91523ea90f19 Mon Sep 17 00:00:00 2001
|
|
From: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
|
Date: Wed, 8 Dec 2021 10:44:00 +0200
|
|
Subject: [PATCH] ath11k: add spectral/CFR buffer validation support
|
|
|
|
Currently there is no validation on the spectral/CFR report
|
|
over the db ring buffers from the hardware. Improper/incomplete
|
|
DMA by the target can result in invalid data received by host.
|
|
Due to this we may populate incorrect data to user space.
|
|
|
|
This buffer validation support fix this issues by filling some
|
|
magic value in the buffer during buffer replenish and check for
|
|
the magic value in the buffer received by the target. If host
|
|
detect magic value in the received buffer it will drop the buffer.
|
|
|
|
Tested-on: IPQ8074 WLAN.HK.2.4.0.1-01467-QCAHKSWPL_SILICONZ-1
|
|
|
|
Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
|
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
|
|
Link: https://lore.kernel.org/r/1637312901-10279-2-git-send-email-quic_vnaralas@quicinc.com
|
|
---
|
|
drivers/net/wireless/ath/ath11k/dbring.c | 30 ++++++++++++++++++++++
|
|
drivers/net/wireless/ath/ath11k/dbring.h | 2 ++
|
|
drivers/net/wireless/ath/ath11k/spectral.c | 14 ++++++++++
|
|
3 files changed, 46 insertions(+)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/dbring.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dbring.c
|
|
@@ -6,6 +6,35 @@
|
|
#include "core.h"
|
|
#include "debug.h"
|
|
|
|
+#define ATH11K_DB_MAGIC_VALUE 0xdeadbeaf
|
|
+
|
|
+int ath11k_dbring_validate_buffer(struct ath11k *ar, void *buffer, u32 size)
|
|
+{
|
|
+ u32 *temp;
|
|
+ int idx;
|
|
+
|
|
+ size = size >> 2;
|
|
+
|
|
+ for (idx = 0, temp = buffer; idx < size; idx++, temp++) {
|
|
+ if (*temp == ATH11K_DB_MAGIC_VALUE)
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void ath11k_dbring_fill_magic_value(struct ath11k *ar,
|
|
+ void *buffer, u32 size)
|
|
+{
|
|
+ u32 *temp;
|
|
+ int idx;
|
|
+
|
|
+ size = size >> 2;
|
|
+
|
|
+ for (idx = 0, temp = buffer; idx < size; idx++, temp++)
|
|
+ *temp++ = ATH11K_DB_MAGIC_VALUE;
|
|
+}
|
|
+
|
|
static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
|
struct ath11k_dbring *ring,
|
|
struct ath11k_dbring_element *buff)
|
|
@@ -26,6 +55,7 @@ static int ath11k_dbring_bufs_replenish(
|
|
|
|
ptr_unaligned = buff->payload;
|
|
ptr_aligned = PTR_ALIGN(ptr_unaligned, ring->buf_align);
|
|
+ ath11k_dbring_fill_magic_value(ar, ptr_aligned, ring->buf_sz);
|
|
paddr = dma_map_single(ab->dev, ptr_aligned, ring->buf_sz,
|
|
DMA_FROM_DEVICE);
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/dbring.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/dbring.h
|
|
@@ -76,4 +76,6 @@ int ath11k_dbring_get_cap(struct ath11k_
|
|
struct ath11k_dbring_cap *db_cap);
|
|
void ath11k_dbring_srng_cleanup(struct ath11k *ar, struct ath11k_dbring *ring);
|
|
void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring);
|
|
+int ath11k_dbring_validate_buffer(struct ath11k *ar, void *data, u32 size);
|
|
+
|
|
#endif /* ATH11K_DBRING_H */
|
|
--- a/drivers/net/wireless/ath/ath11k/spectral.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/spectral.c
|
|
@@ -585,6 +585,7 @@ int ath11k_spectral_process_fft(struct a
|
|
u16 length, freq;
|
|
u8 chan_width_mhz, bin_sz;
|
|
int ret;
|
|
+ u32 check_length;
|
|
|
|
lockdep_assert_held(&ar->spectral.lock);
|
|
|
|
@@ -618,6 +619,13 @@ int ath11k_spectral_process_fft(struct a
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ check_length = sizeof(*fft_report) + (num_bins * ab->hw_params.spectral.fft_sz);
|
|
+ ret = ath11k_dbring_validate_buffer(ar, data, check_length);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ar->ab, "found magic value in fft data, dropping\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
ret = ath11k_spectral_pull_search(ar, data, &search);
|
|
if (ret) {
|
|
ath11k_warn(ab, "failed to pull search report %d\n", ret);
|
|
@@ -751,6 +759,12 @@ static int ath11k_spectral_process_data(
|
|
goto err;
|
|
}
|
|
|
|
+ ret = ath11k_dbring_validate_buffer(ar, data, tlv_len);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ar->ab, "found magic value in spectral summary, dropping\n");
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
summary = (struct spectral_summary_fft_report *)tlv;
|
|
ath11k_spectral_pull_summary(ar, ¶m->meta,
|
|
summary, &summ_rpt);
|