Commit 26a6d527 authored by Lior David's avatar Lior David Committed by Kalle Valo

wil6210: fix length check in __wmi_send

The current length check:
sizeof(cmd) + len > r->entry_size
will allow very large values of len (> U16_MAX - sizeof(cmd))
and can cause a buffer overflow. Fix the check to cover this case.
In addition, ensure the mailbox entry_size is not too small,
since this can also bypass the above check.
Signed-off-by: default avatarLior David <qca_liord@qca.qualcomm.com>
Signed-off-by: default avatarMaya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 144a12a6
...@@ -358,6 +358,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil) ...@@ -358,6 +358,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil)
wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
} }
static bool wil_validate_mbox_regs(struct wil6210_priv *wil)
{
size_t min_size = sizeof(struct wil6210_mbox_hdr) +
sizeof(struct wmi_cmd_hdr);
if (wil->mbox_ctl.rx.entry_size < min_size) {
wil_err(wil, "rx mbox entry too small (%d)\n",
wil->mbox_ctl.rx.entry_size);
return false;
}
if (wil->mbox_ctl.tx.entry_size < min_size) {
wil_err(wil, "tx mbox entry too small (%d)\n",
wil->mbox_ctl.tx.entry_size);
return false;
}
return true;
}
static irqreturn_t wil6210_irq_misc(int irq, void *cookie) static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
{ {
struct wil6210_priv *wil = cookie; struct wil6210_priv *wil = cookie;
...@@ -393,7 +412,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) ...@@ -393,7 +412,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
if (isr & ISR_MISC_FW_READY) { if (isr & ISR_MISC_FW_READY) {
wil_dbg_irq(wil, "IRQ: FW ready\n"); wil_dbg_irq(wil, "IRQ: FW ready\n");
wil_cache_mbox_regs(wil); wil_cache_mbox_regs(wil);
set_bit(wil_status_mbox_ready, wil->status); if (wil_validate_mbox_regs(wil))
set_bit(wil_status_mbox_ready, wil->status);
/** /**
* Actual FW ready indicated by the * Actual FW ready indicated by the
* WMI_FW_READY_EVENTID * WMI_FW_READY_EVENTID
......
...@@ -448,7 +448,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) ...@@ -448,7 +448,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
uint retry; uint retry;
int rc = 0; int rc = 0;
if (sizeof(cmd) + len > r->entry_size) { if (len > r->entry_size - sizeof(cmd)) {
wil_err(wil, "WMI size too large: %d bytes, max is %d\n", wil_err(wil, "WMI size too large: %d bytes, max is %d\n",
(int)(sizeof(cmd) + len), r->entry_size); (int)(sizeof(cmd) + len), r->entry_size);
return -ERANGE; return -ERANGE;
......
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