mwifiex event packets carry a four-byte event cause followed by the event body. The USB and SDIO receive paths read the event cause and then copy adapter->event_body from skb->data + MWIFIEX_EVENT_HEADER_LEN, but pass the full skb->len as the copy length. That makes the source range extend past the skb by the size of the event header. Require the event header before reading the event cause, and copy only the bytes after the header into adapter->event_body. Keep the existing per-path total event-size checks so this stays a narrow bounds fix. Signed-off-by: Pengpeng Hou --- drivers/net/wireless/marvell/mwifiex/sdio.c | 10 ++++++++-- drivers/net/wireless/marvell/mwifiex/usb.c | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -1712,12 +1712,18 @@ case MWIFIEX_TYPE_EVENT: mwifiex_dbg(adapter, EVENT, "info: --- Rx: Event ---\n"); + if (skb->len < MWIFIEX_EVENT_HEADER_LEN) { + mwifiex_dbg(adapter, ERROR, + "event packet too short: %u\n", skb->len); + dev_kfree_skb_any(skb); + return -1; + } adapter->event_cause = get_unaligned_le32(skb->data); - if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE)) + if (skb->len < MAX_EVENT_SIZE) memcpy(adapter->event_body, skb->data + MWIFIEX_EVENT_HEADER_LEN, - skb->len); + skb->len - MWIFIEX_EVENT_HEADER_LEN); /* event cause has been saved to adapter->event_cause */ adapter->event_received = true; --- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -91,7 +91,7 @@ adapter->cmd_resp_received = true; break; case MWIFIEX_USB_TYPE_EVENT: - if (skb->len < sizeof(u32)) { + if (skb->len < MWIFIEX_EVENT_HEADER_LEN) { mwifiex_dbg(adapter, ERROR, "EVENT: skb->len too small\n"); ret = -1; @@ -110,7 +110,8 @@ } memcpy(adapter->event_body, skb->data + - MWIFIEX_EVENT_HEADER_LEN, skb->len); + MWIFIEX_EVENT_HEADER_LEN, + skb->len - MWIFIEX_EVENT_HEADER_LEN); adapter->event_received = true; adapter->event_skb = skb;