[PATCH 1/2] wifi: ath9k: don't read past short WMI command responses
From: Michail Andreas Michalopoulos
Date: Tue Oct 20 2026 - 11:25:46 EST
ath9k_wmi_rsp_callback() copies cmd_rsp_len bytes from the response
without checking how many bytes the device sent. A short or empty
response makes it copy stale bytes from the uninitialised USB REG_IN
buffer into the caller's buffer, e.g. into the value returned by
ath9k_regread().
Commit 93ce8ea70451 ("wifi: ath9k: reject short WMI command responses")
failed such responses with -EMSGSIZE, but AR9271 firmware answers
commands that return nothing with an empty response, so that broke
normal operation and was reverted by commit 90201351a862 ("wifi: atk9k:
Revert "wifi: ath9k: reject short WMI command responses"").
Copy only the bytes that were received and zero the rest of the
caller's buffer instead. Empty responses keep completing successfully,
and callers no longer see bytes the device never sent.
Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Michail Andreas Michalopoulos <mike.michalo@xxxxxxxxx>
---
drivers/net/wireless/ath/ath9k/wmi.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 44e91815a1..76c8dfcc53 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -204,10 +204,20 @@ void ath9k_fatal_work(struct work_struct *work)
static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
{
+ u32 len;
+
skb_pull(skb, sizeof(struct wmi_cmd_hdr));
- if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
- memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
+ if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0) {
+ /*
+ * The firmware may send a shorter (even empty) response than
+ * the caller's buffer, e.g. for commands that return nothing.
+ * Copy only what was received and zero the rest.
+ */
+ len = min(skb->len, wmi->cmd_rsp_len);
+ memcpy(wmi->cmd_rsp_buf, skb->data, len);
+ memset(wmi->cmd_rsp_buf + len, 0, wmi->cmd_rsp_len - len);
+ }
complete(&wmi->cmd_wait);
}
--
2.43.0