* [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing
@ 2026-04-27 8:16 Alexandru Hossu
2026-04-27 8:16 ` [PATCH v3 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop Alexandru Hossu
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-04-27 8:16 UTC (permalink / raw)
To: gregkh, linux-staging, linux-kernel; +Cc: error27, luka.gejak, Alexandru Hossu
v3, addressing Luka's review. No code changes.
- Added Fixes: and Cc: stable@vger.kernel.org to all three patches
- Moved Reviewed-by above Signed-off-by on all three patches
Thanks for the review, Luka.
Alexandru Hossu (3):
staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop
staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and
join_cmd_hdl()
staging: rtl8723bs: fix heap buffer overflow in
rtw_cfg80211_set_wpa_ie()
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 8 ++++++++
drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 6 +++++-
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 8 ++++++++
3 files changed, 21 insertions(+), 1 deletion(-)
--
2.53.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop
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 ` 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
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-04-27 8:16 UTC (permalink / raw)
To: gregkh, linux-staging, linux-kernel
Cc: error27, luka.gejak, Alexandru Hossu, stable
The IE parsing loop in update_beacon_info() advances by
(pIE->length + 2) each iteration but only guards on i < len.
When a malicious AP sends a Beacon whose last IE has only one byte
remaining in the frame (the element_id byte lands at len-1), the loop
reads pIE->length from one byte past the allocated receive buffer.
Additionally, even when the header bytes are in bounds, pIE->length
itself can extend the data window beyond len, passing a truncated IE
to the handler functions.
Add two guards at the top of the loop body:
1. Break if fewer than sizeof(*pIE) bytes remain (can't read header).
2. Break if the IE's declared data extends past len.
Also replace i += (pIE->length + 2) with i += sizeof(*pIE) + pIE->length
for consistency with the sizeof(*pIE) guards added above.
Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
---
drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
index 6a7c09db4cd9..e0d73c267786 100644
--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
@@ -1289,7 +1289,11 @@ void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, stru
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:
@@ -1314,7 +1318,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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 2/3] staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()
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 ` 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
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-04-27 8:16 UTC (permalink / raw)
To: gregkh, linux-staging, linux-kernel
Cc: error27, luka.gejak, Alexandru Hossu, stable
Two IE parsing loops are missing the header bounds checks before they
dereference pIE->length:
- issue_assocreq() walks pmlmeinfo->network.ies to build the
association request. If the stored IE data ends with only an
element_id byte and no length byte, pIE->length is read one byte
past the end of the buffer.
- join_cmd_hdl() walks pnetwork->ies during station join and has
the same problem under the same conditions.
Both buffers are filled from AP beacon and probe-response frames, so a
malicious AP that sends a truncated final IE can trigger the issue.
Apply the two-guard pattern already used in OnAssocRsp():
1. Break if fewer than sizeof(*pIE) bytes remain.
2. Break if the IE's declared data extends past the buffer end.
Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
---
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 884cd39ec756..c646dc2a1741 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -2931,7 +2931,11 @@ void issue_assocreq(struct adapter *padapter)
/* vendor specific IE, such as WPA, WMM, WPS */
for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.ie_length;) {
+ if (i + sizeof(*pIE) > pmlmeinfo->network.ie_length)
+ break;
pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.ies + i);
+ if (i + sizeof(*pIE) + pIE->length > pmlmeinfo->network.ie_length)
+ break;
switch (pIE->element_id) {
case WLAN_EID_VENDOR_SPECIFIC:
@@ -5324,7 +5328,11 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
/* sizeof(struct ndis_802_11_fix_ie) */
for (i = _FIXED_IE_LENGTH_; i < pnetwork->ie_length;) {
+ if (i + sizeof(*pIE) > pnetwork->ie_length)
+ break;
pIE = (struct ndis_80211_var_ie *)(pnetwork->ies + i);
+ if (i + sizeof(*pIE) + pIE->length > pnetwork->ie_length)
+ break;
switch (pIE->element_id) {
case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 3/3] staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()
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 ` 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:25 ` [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
4 siblings, 0 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-04-27 8:16 UTC (permalink / raw)
To: gregkh, linux-staging, linux-kernel
Cc: error27, luka.gejak, Alexandru Hossu, stable
supplicant_ie is a 256-byte array in struct security_priv. The WPA and
WPA2 IE copy paths use:
memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
where wpa_ielen is the raw IE length field (u8, 0-255). When a local user
supplies a connect request via nl80211 with a crafted WPA IE of length 255,
wpa_ielen + 2 equals 257, overflowing the 256-byte buffer by one byte into
the adjacent last_mic_err_time field.
rtw_parse_wpa_ie() does not prevent this: its length consistency check
compares *(wpa_ie+1) against (u8)(wpa_ie_len-2), which is (u8)(255) == 255
when wpa_ie_len = 257, so the check passes silently.
Add explicit bounds checks for both the WPA and WPA2 paths before the
memcpy, rejecting any IE whose total size (wpa_ielen + 2) exceeds the
supplicant_ie buffer.
Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
---
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
index 098456e97c96..3d930d9af184 100644
--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
@@ -1443,6 +1443,10 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
if (pwpa && wpa_ielen > 0) {
+ if (wpa_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
+ ret = -EINVAL;
+ goto exit;
+ }
if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
@@ -1452,6 +1456,10 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
if (pwpa2 && wpa2_ielen > 0) {
+ if (wpa2_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
+ ret = -EINVAL;
+ goto exit;
+ }
if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing
2026-04-27 8:16 [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
` (2 preceding siblings ...)
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 ` Greg KH
2026-05-05 17:38 ` [PATCH v4 " Alexandru Hossu
2026-05-05 17:25 ` [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
4 siblings, 1 reply; 10+ messages in thread
From: Greg KH @ 2026-05-04 14:11 UTC (permalink / raw)
To: Alexandru Hossu; +Cc: linux-staging, linux-kernel, error27, luka.gejak
On Mon, Apr 27, 2026 at 10:16:23AM +0200, Alexandru Hossu wrote:
> v3, addressing Luka's review. No code changes.
>
> - Added Fixes: and Cc: stable@vger.kernel.org to all three patches
> - Moved Reviewed-by above Signed-off-by on all three patches
Please address the review comments found here:
https://sashiko.dev/#/patchset/20260427081626.3393697-1-hossu.alexandru@gmail.com
when you resubmit. And have you tested this on real hardware?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing
2026-04-27 8:16 [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
` (3 preceding siblings ...)
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:25 ` Alexandru Hossu
4 siblings, 0 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-05-05 17:25 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, linux-kernel, error27, luka.gejak
[-- Attachment #1: Type: text/plain, Size: 383 bytes --]
Hi Greg,
To answer your question about hardware: I do not have rtl8723bs hardware
available. The patches in this series are derived from static analysis
of the code, cross-checking against the 802.11 spec, and reviewing the
patterns already in use elsewhere in the same driver.
I am working on v4 to address the sashiko review comments and will send
it shortly.
Thanks,
Alexandru
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing
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 ` Alexandru Hossu
2026-05-05 17:38 ` [PATCH v4 1/3] staging: rtl8723bs: fix OOB reads in update_beacon_info() and bwmode_update_check() Alexandru Hossu
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-05-05 17:38 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, linux-kernel, error27, luka.gejak, stable
v4, addressing the sashiko review comments on v3.
Regarding hardware: I do not have rtl8723bs hardware available. The
patches in this series are derived from static analysis of the code,
cross-checking against the 802.11 spec, and reviewing the patterns
already in use elsewhere in the same driver.
What changed in v4:
Patch 1 (update_beacon_info, bwmode_update_check):
- Added unsigned underflow guard: if pkt_len < _BEACON_IE_OFFSET_ +
WLAN_HDR_A3_LEN the subtraction that computes len would wrap to a
very large value. Return early.
- Swapped the WLAN_EID_VENDOR_SPECIFIC condition so pIE->length ==
WLAN_WMM_LEN is checked before memcmp(pIE->data, WMM_PARA_OUI, 6)
to prevent the 6-byte read on a short IE.
- Fixed bwmode_update_check(): changed pIE->length >
sizeof(struct HT_info_element) to != to also reject IEs shorter
than the struct, preventing the read of infos[0] on a zero-length IE.
Patch 2 (issue_assocreq, join_cmd_hdl):
- Added pIE->length >= 4 guard before the 4-byte OUI memcmps in both
WLAN_EID_VENDOR_SPECIFIC cases.
- In issue_assocreq() WLAN_EID_HT_CAPABILITY: added minimum length
check and replaced pIE->length with sizeof(struct HT_caps_element)
in rtw_set_ie() to prevent reads past the HT_caps struct.
- In join_cmd_hdl() WLAN_EID_HT_OPERATION: added minimum length check
before casting pIE->data to struct HT_info_element * and reading
infos[0].
Patch 3 (rtw_get_wps_ie, rtw_cfg80211_set_wpa_ie):
- Added two bounds checks in rtw_get_wps_ie(): break if fewer than
two header bytes remain; break if the declared payload extends past
in_len. Added in_ie[cnt + 1] >= 4 guard before the 4-byte WPS OUI
memcmp.
Alexandru Hossu (3):
staging: rtl8723bs: fix OOB reads in update_beacon_info() and
bwmode_update_check()
staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and
join_cmd_hdl()
staging: rtl8723bs: fix OOB reads in rtw_get_wps_ie() and
rtw_cfg80211_set_wpa_ie()
.../staging/rtl8723bs/core/rtw_ieee80211.c | 9 +++++-
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 30 ++++++++++++++-----
.../staging/rtl8723bs/core/rtw_wlan_util.c | 14 +++++++--
.../staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 8 +++++
4 files changed, 50 insertions(+), 11 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/3] staging: rtl8723bs: fix OOB reads in update_beacon_info() and bwmode_update_check()
2026-05-05 17:38 ` [PATCH v4 " Alexandru Hossu
@ 2026-05-05 17:38 ` Alexandru Hossu
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
2 siblings, 0 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-05-05 17:38 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, linux-kernel, error27, luka.gejak, stable
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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/3] staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()
2026-05-05 17:38 ` [PATCH v4 " Alexandru Hossu
2026-05-05 17:38 ` [PATCH v4 1/3] staging: rtl8723bs: fix OOB reads in update_beacon_info() and bwmode_update_check() Alexandru Hossu
@ 2026-05-05 17:38 ` 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
2 siblings, 0 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-05-05 17:38 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, linux-kernel, error27, luka.gejak, stable
Five out-of-bounds read paths in the IE parsing loops of
issue_assocreq() and join_cmd_hdl():
1. Missing IE header bounds checks (both functions).
Both loops advance by pIE->length + 2 per iteration but only guard
on i < ie_length. When the buffer ends with a single element_id
byte and no length byte, the loop reads pIE->length from one byte
past the end of the buffer. Even when both header bytes are in
bounds, pIE->length can extend the data window past ie_length,
silently passing a truncated IE to handler functions. Add two
guards at the top of each loop: break if fewer than sizeof(*pIE)
bytes remain, and break if the declared IE payload extends past
ie_length.
2. Vendor-specific OUI comparison reads 4 bytes past a possibly short
IE payload (both functions).
For WLAN_EID_VENDOR_SPECIFIC, the code calls memcmp(pIE->data,
OUI, 4) on RTW_WPA_OUI, WMM_OUI, and WPS_OUI without first
verifying that pIE->length is at least 4. A short IE at the end
of the frame causes the memcmp to read into adjacent frame data.
Add pIE->length >= 4 guard before the comparisons.
3. HT Capability IE memcpy reads sizeof(struct HT_caps_element) bytes
from an IE that may be shorter (issue_assocreq only).
The WLAN_EID_HT_CAPABILITY handler copies:
memcpy(&pmlmeinfo->HT_caps, pIE->data, sizeof(struct HT_caps_element));
If pIE->length < sizeof(struct HT_caps_element), the memcpy reads
beyond the end of the IE payload into adjacent frame data. Add a
minimum length check and skip the IE if it is too short.
4. rtw_set_ie called with untrusted pIE->length for HT Capability
(issue_assocreq only).
After the memcpy the code passes pIE->length directly to
rtw_set_ie() as the IE body length. If pIE->length exceeds
sizeof(struct HT_caps_element), rtw_set_ie copies that many bytes
from pmlmeinfo->HT_caps, reading past the end of the struct into
adjacent fields. Use sizeof(struct HT_caps_element) instead.
5. HT Operation IE accessed without minimum length check (join_cmd_hdl
only).
The WLAN_EID_HT_OPERATION handler casts pIE->data to
struct HT_info_element * and reads pht_info->infos[0] (offset 1)
without verifying pIE->length >= sizeof(struct HT_info_element).
A zero- or one-byte HT Operation IE causes an out-of-bounds read.
Add a minimum length check and break if the IE is too short.
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 pIE->length >= 4 guard before the 4-byte OUI memcmps in the
WLAN_EID_VENDOR_SPECIFIC cases of both functions (sashiko review of v3).
- In issue_assocreq() WLAN_EID_HT_CAPABILITY: add minimum length check
(pIE->length < sizeof(struct HT_caps_element)) and use
sizeof(struct HT_caps_element) instead of pIE->length in rtw_set_ie()
to prevent OOB reads past the HT_caps struct (sashiko review of v3).
- In join_cmd_hdl() WLAN_EID_HT_OPERATION: add minimum length check
(pIE->length < sizeof(struct HT_info_element)) before casting pIE->data
to struct HT_info_element * and reading infos[0] (sashiko review of v3).
Changes in v3:
- No code changes from v2.
Changes in v2:
- Add IE loop header and payload bounds checks for issue_assocreq()
and join_cmd_hdl().
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 30 ++++++++++++++-----
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 5f00fe282d1b..0c130d0f9a48 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -2925,13 +2925,18 @@ void issue_assocreq(struct adapter *padapter)
/* vendor specific IE, such as WPA, WMM, WPS */
for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.ie_length;) {
+ if (i + sizeof(*pIE) > pmlmeinfo->network.ie_length)
+ break;
pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.ies + i);
+ if (i + sizeof(*pIE) + pIE->length > pmlmeinfo->network.ie_length)
+ break;
switch (pIE->element_id) {
case WLAN_EID_VENDOR_SPECIFIC:
- if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
+ if (pIE->length >= 4 &&
+ ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
(!memcmp(pIE->data, WMM_OUI, 4)) ||
- (!memcmp(pIE->data, WPS_OUI, 4))) {
+ (!memcmp(pIE->data, WPS_OUI, 4)))) {
vs_ie_length = pIE->length;
if ((!padapter->registrypriv.wifi_spec) && (!memcmp(pIE->data, WPS_OUI, 4))) {
/* Commented by Kurt 20110629
@@ -2953,8 +2958,10 @@ void issue_assocreq(struct adapter *padapter)
case WLAN_EID_HT_CAPABILITY:
if (padapter->mlmepriv.htpriv.ht_option) {
if (!(is_ap_in_tkip(padapter))) {
+ if (pIE->length < sizeof(struct HT_caps_element))
+ break;
memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
- pframe = rtw_set_ie(pframe, WLAN_EID_HT_CAPABILITY, pIE->length, (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
+ pframe = rtw_set_ie(pframe, WLAN_EID_HT_CAPABILITY, sizeof(struct HT_caps_element), (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
}
}
break;
@@ -2967,7 +2974,7 @@ void issue_assocreq(struct adapter *padapter)
break;
}
- i += (pIE->length + 2);
+ i += sizeof(*pIE) + pIE->length;
}
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
@@ -5318,11 +5325,15 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
/* sizeof(struct ndis_802_11_fix_ie) */
for (i = _FIXED_IE_LENGTH_; i < pnetwork->ie_length;) {
+ if (i + sizeof(*pIE) > pnetwork->ie_length)
+ break;
pIE = (struct ndis_80211_var_ie *)(pnetwork->ies + i);
+ if (i + sizeof(*pIE) + pIE->length > pnetwork->ie_length)
+ break;
switch (pIE->element_id) {
case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
- if (!memcmp(pIE->data, WMM_OUI, 4))
+ if (pIE->length >= 4 && !memcmp(pIE->data, WMM_OUI, 4))
WMM_param_handler(padapter, pIE);
break;
@@ -5335,7 +5346,12 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
/* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
{
- struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
+ struct HT_info_element *pht_info;
+
+ if (pIE->length < sizeof(struct HT_info_element))
+ break;
+
+ pht_info = (struct HT_info_element *)(pIE->data);
if (pnetwork->configuration.ds_config <= 14) {
if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
@@ -5366,7 +5382,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
break;
}
- i += (pIE->length + 2);
+ i += sizeof(*pIE) + pIE->length;
}
/* check channel, bandwidth, offset and switch */
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] staging: rtl8723bs: fix OOB reads in rtw_get_wps_ie() and rtw_cfg80211_set_wpa_ie()
2026-05-05 17:38 ` [PATCH v4 " Alexandru Hossu
2026-05-05 17:38 ` [PATCH v4 1/3] staging: rtl8723bs: fix OOB reads in update_beacon_info() and bwmode_update_check() Alexandru Hossu
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 ` Alexandru Hossu
2 siblings, 0 replies; 10+ messages in thread
From: Alexandru Hossu @ 2026-05-05 17:38 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, linux-kernel, error27, luka.gejak, stable
Three out-of-bounds read or write paths:
1. rtw_get_wps_ie() reads the IE length byte without a header bounds
check.
The loop only guards on cnt < in_len, so when the buffer ends with
a single element_id byte and no length byte, in_ie[cnt + 1] is read
one byte past the end of the buffer. Add a check that at least
two header bytes remain (cnt + 2 <= in_len) before reading
in_ie[cnt + 1].
2. rtw_get_wps_ie() does not verify the declared IE payload fits within
in_len.
After reading the length byte, the loop does not verify that
in_ie[cnt + 1] + 2 bytes are available starting at cnt. A crafted
length value can cause the subsequent memcmp and memcpy to read past
the end of the buffer. Add a check that the full IE (header plus
payload) fits within in_len.
3. rtw_get_wps_ie() reads 4 bytes from the IE payload via memcmp
without checking that pIE->length >= 4.
For WLAN_EID_VENDOR_SPECIFIC, the code calls
memcmp(&in_ie[cnt + 2], wps_oui, 4) without first verifying that
the IE payload is at least 4 bytes long. Add an in_ie[cnt + 1] >= 4
guard before the comparison.
4. rtw_cfg80211_set_wpa_ie() can overflow the 256-byte supplicant_ie
buffer.
supplicant_ie is a 256-byte array in struct security_priv. The WPA
and WPA2 IE copy paths use memcpy(..., wpa_ielen + 2) where
wpa_ielen is the raw IE length field (u8, 0-255). When a local
user supplies a connect request via nl80211 with a crafted WPA IE
of length 255, wpa_ielen + 2 equals 257, overflowing the 256-byte
buffer. Add explicit bounds checks for both paths before memcpy.
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 two IE bounds checks in rtw_get_wps_ie(): break if fewer than two
header bytes remain, and break if the declared payload extends past
in_len; add in_ie[cnt + 1] >= 4 guard before the 4-byte WPS OUI memcmp
(sashiko review of v3).
Changes in v3:
- No code changes from v2.
Changes in v2:
- Add explicit size checks in rtw_cfg80211_set_wpa_ie() before memcpy
to prevent the 256-byte supplicant_ie buffer overflow.
drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 9 ++++++++-
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 8 ++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
index 72b7f731dd47..d6d5f3a8db4c 100644
--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
@@ -661,7 +661,14 @@ u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
while (cnt < in_len) {
eid = in_ie[cnt];
- if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) {
+ if (cnt + 2 > in_len)
+ break;
+
+ if (in_ie[cnt + 1] + 2 > in_len - cnt)
+ break;
+
+ if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (in_ie[cnt + 1] >= 4) &&
+ (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) {
wpsie_ptr = &in_ie[cnt];
if (wps_ie)
diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
index fd3bae31b0ed..e7ba5ccfa03c 100644
--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
@@ -1445,6 +1445,10 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
if (pwpa && wpa_ielen > 0) {
+ if (wpa_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
+ ret = -EINVAL;
+ goto exit;
+ }
if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
@@ -1454,6 +1458,10 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
if (pwpa2 && wpa2_ielen > 0) {
+ if (wpa2_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
+ ret = -EINVAL;
+ goto exit;
+ }
if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-05-05 17:38 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH v4 1/3] staging: rtl8723bs: fix OOB reads in update_beacon_info() and bwmode_update_check() Alexandru Hossu
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-05 17:25 ` [PATCH v3 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox