From: Tristan Madani The firmware-controlled frame length at buffer[6..7] is decremented by 1 and used as the kmemdup size without validating the value. When the firmware sends 0, the u16 subtraction wraps to 65535, causing a 64KB out-of-bounds read from the RX buffer. For non-zero but inflated values, the read exceeds the actual packet data. Add validation that the frame length is at least 1 and fits within the available buffer. Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver") Signed-off-by: Tristan Madani --- Changes in v3: - Regenerated from wireless-next with proper git format-patch to produce valid index hashes (v2 had post-processed index lines). Changes in v2: - No code changes from v1. drivers/net/wireless/microchip/wilc1000/hif.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c index 009c4770a6f95..473e406c98d87 100644 --- a/drivers/net/wireless/microchip/wilc1000/hif.c +++ b/drivers/net/wireless/microchip/wilc1000/hif.c @@ -1576,6 +1576,7 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) struct wilc_vif *vif; int srcu_idx; int result; + u16 frame_len; int id; id = get_unaligned_le32(&buffer[length - 4]); @@ -1594,7 +1595,15 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) if (IS_ERR(msg)) goto out; - msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1; + frame_len = get_unaligned_le16(&buffer[6]); + if (frame_len == 0 || frame_len > length - 9) { + netdev_err(vif->ndev, + "%s: invalid frame_len %u (buffer %u)\n", + __func__, frame_len, length); + kfree(msg); + goto out; + } + msg->body.net_info.frame_len = frame_len - 1; msg->body.net_info.rssi = buffer[8]; msg->body.net_info.mgmt = kmemdup(&buffer[9], msg->body.net_info.frame_len, -- 2.47.3