Commit d3d358ef authored by Venkateswara Naralasetty's avatar Venkateswara Naralasetty Committed by Kalle Valo

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: default avatarVenkateswara Naralasetty <quic_vnaralas@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/1637312901-10279-2-git-send-email-quic_vnaralas@quicinc.com
parent 7e2ea2e9
......@@ -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(struct ath11k *ar,
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);
......
......@@ -76,4 +76,6 @@ int ath11k_dbring_get_cap(struct ath11k_base *ab,
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 */
......@@ -581,6 +581,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
u16 length, freq;
u8 chan_width_mhz, bin_sz;
int ret;
u32 check_length;
lockdep_assert_held(&ar->spectral.lock);
......@@ -614,6 +615,13 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
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);
......@@ -747,6 +755,12 @@ static int ath11k_spectral_process_data(struct ath11k *ar,
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, &param->meta,
summary, &summ_rpt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment