Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 875379d2 authored by Lior David's avatar Lior David Committed by Gerrit - the friendly Code Review server
Browse files

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.

Change-Id: Iecb4f53ef05da0e015bc954b57b0e40debb7c8b7
Signed-off-by: default avatarLior David <liord@codeaurora.org>
parent 5398459b
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -356,6 +356,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil)
	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)
{
	struct wil6210_priv *wil = cookie;
@@ -391,6 +410,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
	if (isr & ISR_MISC_FW_READY) {
		wil_dbg_irq(wil, "IRQ: FW ready\n");
		wil_cache_mbox_regs(wil);
		if (wil_validate_mbox_regs(wil))
			set_bit(wil_status_mbox_ready, wil->status);
		/**
		 * Actual FW ready indicated by the
+1 −1
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
	uint retry;
	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",
			(int)(sizeof(cmd) + len), r->entry_size);
		return -ERANGE;