[PATCH v4 2/5] staging: rtl8723bs: fix integer underflow in TKIP MIC verification

Delene Tchio Romuald
2026-04-15T18:55:42Z

In recvframe_chkmic(), the payload length is computed as:

datalen = precvframe->u.hdr.len - prxattrib->hdrlen
- prxattrib->iv_len - prxattrib->icv_len - 8;

All operands are unsigned. If the receive frame is shorter than the
sum of the header, IV, ICV and MIC sizes, this subtraction wraps
around and datalen becomes a huge unsigned value. That value is then
passed to rtw_secmicappend(), which reads past the end of the
receive buffer and can leak kernel memory or trigger a crash.

An attacker within WiFi radio range can exploit this by sending a
crafted short TKIP-encrypted frame. No authentication is required.

Validate that the frame is large enough for the TKIP MIC
computation before the subtraction.

Found by reviewing length arithmetic in the TKIP receive path.
Not tested on hardware.

Fixes: 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
Signed-off-by: Delene Tchio Romuald <delenetchior1@gmail.com>
---
v4: add Fixes: tag and Cc: stable (Dan Carpenter); carry Luka Gejak's
Reviewed-by.
v3: rebased on staging-next; sent as numbered series with proper
Cc from get_maintainer.pl.
v2: rebased on staging-next (v1 was based on v7.0-rc6 and did not
apply).

drivers/staging/rtl8723bs/core/rtw_recv.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c
index a739c2bada2a1..00b69571bbb83 100644
--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
+++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
@@ -390,6 +390,13 @@ static signed int recvframe_chkmic(struct adapter *adapter, union recv_frame *p
mickey = &stainfo->dot11tkiprxmickey.skey[0];
}

+ /* Ensure the frame is large enough for TKIP MIC verification */
+ if (precvframe->u.hdr.len <= prxattrib->hdrlen +
+ prxattrib->iv_len + prxattrib->icv_len + 8) {
+ res = _FAIL;
+ goto exit;
+ }
+
datalen = precvframe->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8;/* icv_len included the mic code */
pframe = precvframe->u.hdr.rx_data;
payload = pframe + prxattrib->hdrlen + prxattrib->iv_len;
--
2.43.0