From: Alexandru Hossu <hossu.alexandru@gmail.com>
To: gregkh@linuxfoundation.org
Cc: linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org,
error27@gmail.com, luka.gejak@linux.dev, stable@vger.kernel.org
Subject: [PATCH v4 1/3] staging: rtl8723bs: fix OOB reads in update_beacon_info() and bwmode_update_check()
Date: Tue, 5 May 2026 19:38:16 +0200 [thread overview]
Message-ID: <20260505173818.3674164-2-hossu.alexandru@gmail.com> (raw)
In-Reply-To: <20260505173818.3674164-1-hossu.alexandru@gmail.com>
Four out-of-bounds read paths in Beacon IE processing:
1. Unsigned underflow in len computation.
update_beacon_info() computes:
len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
where len is unsigned int. If pkt_len is smaller than
_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN (36 bytes), the subtraction
wraps to a very large value, causing the IE loop to iterate over
memory far beyond the receive buffer. Add an early return when
pkt_len is too small.
2. IE header and payload may extend past the packet end.
The IE loop advances by pIE->length + 2 per iteration but only
guards on i < len. When the last IE has only one byte left in
the frame, the loop reads pIE->length from pframe[len], one byte
past the receive buffer. Even when the header bytes are in bounds,
pIE->length can point the data window past len, silently passing a
truncated IE to handler functions. Add two guards: break if fewer
than sizeof(*pIE) bytes remain, and break if the declared IE payload
extends past len.
3. WMM OUI comparison reads 6 bytes past a possibly short IE payload.
For WLAN_EID_VENDOR_SPECIFIC, the code calls
memcmp(pIE->data, WMM_PARA_OUI, 6) before checking
pIE->length == WLAN_WMM_LEN. An IE with pIE->length < 6 causes
memcmp to read into adjacent frame data. Swap the condition so the
length check comes first.
4. bwmode_update_check() missing minimum IE length check.
bwmode_update_check() rejects IEs longer than
sizeof(struct HT_info_element) but accepts any shorter length,
including zero. After the check it casts pIE->data to
struct HT_info_element * and reads infos[0] (offset 1), which is
out of bounds when pIE->length is 0 or 1. Change the guard from
> to != to require the IE to be exactly the expected size.
Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
---
Changes in v4:
- Add pkt_len < _BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN guard before the
len subtraction to prevent unsigned underflow (sashiko review of v3).
- Swap WLAN_EID_VENDOR_SPECIFIC condition: check pIE->length ==
WLAN_WMM_LEN before memcmp to avoid reading 6 bytes from a short IE
payload (sashiko review of v3).
- Fix bwmode_update_check(): change > sizeof(struct HT_info_element) to
!= sizeof(struct HT_info_element) to also reject IEs shorter than the
expected size, preventing the read of infos[0] on a zero-length IE
(sashiko review of v3).
Changes in v3:
- No code changes from v2.
Changes in v2:
- Add IE loop header and payload bounds checks in update_beacon_info().
- Use sizeof(*pIE) + pIE->length instead of pIE->length + 2 for
consistency with the sizeof(*pIE) guards (Dan Carpenter).
drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
index 6a7c09db4cd9..7ccfaa538ebb 100644
--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
@@ -850,7 +850,7 @@ static void bwmode_update_check(struct adapter *padapter, struct ndis_80211_var_
if (phtpriv->ht_option == false)
return;
- if (pIE->length > sizeof(struct HT_info_element))
+ if (pIE->length != sizeof(struct HT_info_element))
return;
pHT_info = (struct HT_info_element *)pIE->data;
@@ -1286,15 +1286,23 @@ void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, stru
unsigned int len;
struct ndis_80211_var_ie *pIE;
+ if (pkt_len < _BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN)
+ return;
+
len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
for (i = 0; i < len;) {
+ if (i + sizeof(*pIE) > len)
+ break;
pIE = (struct ndis_80211_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
+ if (i + sizeof(*pIE) + pIE->length > len)
+ break;
switch (pIE->element_id) {
case WLAN_EID_VENDOR_SPECIFIC:
/* to update WMM parameter set while receiving beacon */
- if (!memcmp(pIE->data, WMM_PARA_OUI, 6) && pIE->length == WLAN_WMM_LEN) /* WMM */
+ if (pIE->length == WLAN_WMM_LEN &&
+ !memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */
if (WMM_param_handler(padapter, pIE))
report_wmm_edca_update(padapter);
@@ -1314,7 +1322,7 @@ void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, stru
break;
}
- i += (pIE->length + 2);
+ i += sizeof(*pIE) + pIE->length;
}
}
--
2.53.0
next prev parent reply other threads:[~2026-05-05 17:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-27 8:16 [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
2026-04-27 8:16 ` [PATCH v3 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop Alexandru Hossu
2026-04-27 8:16 ` [PATCH v3 2/3] staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl() Alexandru Hossu
2026-04-27 8:16 ` [PATCH v3 3/3] staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie() Alexandru Hossu
2026-05-04 14:11 ` [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Greg KH
2026-05-05 17:38 ` [PATCH v4 " Alexandru Hossu
2026-05-05 17:38 ` Alexandru Hossu [this message]
2026-05-05 17:38 ` [PATCH v4 2/3] staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl() Alexandru Hossu
2026-05-05 17:38 ` [PATCH v4 3/3] staging: rtl8723bs: fix OOB reads in rtw_get_wps_ie() and rtw_cfg80211_set_wpa_ie() Alexandru Hossu
2026-05-11 12:42 ` [PATCH v4 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Greg KH
2026-05-05 17:25 ` [PATCH v3 " Alexandru Hossu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260505173818.3674164-2-hossu.alexandru@gmail.com \
--to=hossu.alexandru@gmail.com \
--cc=error27@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-staging@lists.linux.dev \
--cc=luka.gejak@linux.dev \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox