[PATCH v4 4/5] staging: rtl8723bs: fix out-of-bounds reads in IE parsing functions

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

rtw_get_wapi_ie(), rtw_get_sec_ie() and rtw_get_wps_ie() walk a
buffer of Information Elements using the TLV length field without
first verifying that the length byte itself is inside the buffer,
and without verifying that the element's declared length fits
inside the remaining buffer. Both conditions can be reached with
crafted input, causing reads past the end of the buffer.

An attacker within WiFi radio range can exploit this by sending
crafted beacon or probe-response frames carrying truncated or
oversized IEs. No authentication is required.

Ensure the length byte is inside the buffer (cnt + 1 < in_len)
and break out of the loop if the declared element length would
read past in_len.

Found by reviewing bounds checks in IE walkers.
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_ieee80211.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
index 72b7f731dd471..e0fed3f42de0c 100644
--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
@@ -582,9 +582,12 @@ int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len)

cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);

- while (cnt < in_len) {
+ while (cnt + 1 < in_len) {
authmode = in_ie[cnt];

+ if (cnt + 2 + in_ie[cnt + 1] > in_len)
+ break;
+
if (authmode == WLAN_EID_BSS_AC_ACCESS_DELAY &&
(!memcmp(&in_ie[cnt + 6], wapi_oui1, 4) ||
!memcmp(&in_ie[cnt + 6], wapi_oui2, 4))) {
@@ -615,9 +618,12 @@ void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie

cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);

- while (cnt < in_len) {
+ while (cnt + 1 < in_len) {
authmode = in_ie[cnt];

+ if (cnt + 2 + in_ie[cnt + 1] > in_len)
+ break;
+
if ((authmode == WLAN_EID_VENDOR_SPECIFIC) &&
(!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
if (wpa_ie)
@@ -658,9 +664,12 @@ u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)

cnt = 0;

- while (cnt < in_len) {
+ while (cnt + 1 < in_len) {
eid = in_ie[cnt];

+ if (cnt + 2 + in_ie[cnt + 1] > in_len)
+ break;
+
if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) {
wpsie_ptr = &in_ie[cnt];

--
2.43.0