wifi: ath9k: reject short WMI command responses

ath9k_wmi_rsp_callback() removes the validated WMI header and copies
the number of bytes expected by the waiting command into its response
buffer. A device response shorter than that expectation can therefore
be read beyond the skb payload.

Record -EMSGSIZE for a short response, complete the waiter, and return
the stored status from the command path. This also prevents callers from
consuming stale response bytes as a successful reply.

Fixes: fb9987d0f7 ("ath9k_htc: Support for AR9271 chipset.")
Assisted-by: LLM
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260814075837.20005-1-pengpeng@iscas.ac.cn
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
Pengpeng Hou 2026-08-14 15:58:37 +08:00 committed by Jeff Johnson
parent 1af8dc9ca7
commit 93ce8ea704
2 changed files with 15 additions and 2 deletions

View File

@ -206,9 +206,16 @@ static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
{
skb_pull(skb, sizeof(struct wmi_cmd_hdr));
if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
if (wmi->cmd_rsp_buf && wmi->cmd_rsp_len) {
if (skb->len < wmi->cmd_rsp_len) {
wmi->cmd_rsp_status = -EMSGSIZE;
goto complete;
}
memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
}
wmi->cmd_rsp_status = 0;
complete:
complete(&wmi->cmd_wait);
}
@ -300,6 +307,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
/* record the rsp buffer and length */
wmi->cmd_rsp_buf = rsp_buf;
wmi->cmd_rsp_len = rsp_len;
wmi->cmd_rsp_status = 0;
wmi->last_seq_id = wmi->tx_seq_id;
spin_unlock_irqrestore(&wmi->wmi_lock, flags);
@ -356,9 +364,13 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
return -ETIMEDOUT;
}
spin_lock_irqsave(&wmi->wmi_lock, flags);
ret = wmi->cmd_rsp_status;
spin_unlock_irqrestore(&wmi->wmi_lock, flags);
mutex_unlock(&wmi->op_mutex);
return 0;
return ret;
out:
ath_dbg(common, WMI, "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));

View File

@ -157,6 +157,7 @@ struct wmi {
u16 tx_seq_id;
u8 *cmd_rsp_buf;
u32 cmd_rsp_len;
int cmd_rsp_status;
bool stopped;
struct list_head pending_tx_events;