* [PATCH 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop
2026-04-24 15:19 [PATCH 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
@ 2026-04-24 15:19 ` Alexandru Hossu
2026-04-25 11:42 ` Dan Carpenter
2026-04-24 15:19 ` [PATCH 2/3] staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl() Alexandru Hossu
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Alexandru Hossu @ 2026-04-24 15:19 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, Alexandru Hossu
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 IE area.
Additionally, even when the header bytes are in bounds, pIE->length itself
can extend the data window beyond len, silently passing a truncated IE to
handler functions such as bwmode_update_check() and ERP_IE_handler().
The parallel fix already applied to OnAssocRsp() uses two guards:
1. Break if fewer than sizeof(*pIE) bytes remain (can't read the header).
2. Break if the IE's declared data extends past the frame boundary.
Apply the same pattern to update_beacon_info().
Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
---
drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
index b75e7f4f8d27..551d7200d3a9 100644
--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
@@ -1292,7 +1292,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:
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop
2026-04-24 15:19 ` [PATCH 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop Alexandru Hossu
@ 2026-04-25 11:42 ` Dan Carpenter
0 siblings, 0 replies; 7+ messages in thread
From: Dan Carpenter @ 2026-04-25 11:42 UTC (permalink / raw)
To: Alexandru Hossu; +Cc: gregkh, linux-staging
On Fri, Apr 24, 2026 at 05:19:30PM +0200, Alexandru Hossu wrote:
> 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 IE area.
>
> Additionally, even when the header bytes are in bounds, pIE->length itself
> can extend the data window beyond len, silently passing a truncated IE to
> handler functions such as bwmode_update_check() and ERP_IE_handler().
>
> The parallel fix already applied to OnAssocRsp() uses two guards:
> 1. Break if fewer than sizeof(*pIE) bytes remain (can't read the header).
> 2. Break if the IE's declared data extends past the frame boundary.
>
> Apply the same pattern to update_beacon_info().
>
> Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
> ---
> drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
> index b75e7f4f8d27..551d7200d3a9 100644
> --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
> +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
> @@ -1292,7 +1292,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;
At the end of the function it does:
i += (pIE->length + 2);
Could you change that to:
i += sizeof(*pIE) + pIE->length;
The original works, but it would be better if all three checks were
consistent.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()
2026-04-24 15:19 [PATCH 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
2026-04-24 15:19 ` [PATCH 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop Alexandru Hossu
@ 2026-04-24 15:19 ` Alexandru Hossu
2026-04-24 15:19 ` [PATCH 3/3] staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie() Alexandru Hossu
2026-04-24 16:05 ` [PATCH 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Luka Gejak
3 siblings, 0 replies; 7+ messages in thread
From: Alexandru Hossu @ 2026-04-24 15:19 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, Alexandru Hossu
Two IE parsing loops lack header bounds checks before dereferencing
pIE->length:
- issue_assocreq() iterates over pmlmeinfo->network.ies to build the
association request. If the stored IE data ends with only an
element_id byte (no length byte), pIE->length is read one byte past
the buffer boundary.
- join_cmd_hdl() iterates over pnetwork->ies during station join.
The same truncated-IE scenario causes an identical OOB read.
Both buffers are populated from AP beacon/probe-response frames, so a
malicious AP that advertises a short 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.
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 9666226a60bb..264d070fc7ba 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -2929,7 +2929,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:
@@ -5322,7 +5326,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] 7+ messages in thread* [PATCH 3/3] staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()
2026-04-24 15:19 [PATCH 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
2026-04-24 15:19 ` [PATCH 1/3] staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop Alexandru Hossu
2026-04-24 15:19 ` [PATCH 2/3] staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl() Alexandru Hossu
@ 2026-04-24 15:19 ` Alexandru Hossu
2026-04-25 12:10 ` Dan Carpenter
2026-04-24 16:05 ` [PATCH 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Luka Gejak
3 siblings, 1 reply; 7+ messages in thread
From: Alexandru Hossu @ 2026-04-24 15:19 UTC (permalink / raw)
To: gregkh; +Cc: linux-staging, Alexandru Hossu
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.
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 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] 7+ messages in thread* Re: [PATCH 3/3] staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()
2026-04-24 15:19 ` [PATCH 3/3] staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie() Alexandru Hossu
@ 2026-04-25 12:10 ` Dan Carpenter
0 siblings, 0 replies; 7+ messages in thread
From: Dan Carpenter @ 2026-04-25 12:10 UTC (permalink / raw)
To: Alexandru Hossu; +Cc: gregkh, linux-staging
On Fri, Apr 24, 2026 at 05:19:32PM +0200, Alexandru Hossu wrote:
> 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.
>
> 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 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);
The rtw_get_wpa_ie() function is pretty suspect... :P
KTODO: Fix the buffer overflows in rtw_get_wpa_ie()
Otherwise this patch looks like it fixes a real bug and doesn't introduce
any regressions...
regards,
dan carpenter
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing
2026-04-24 15:19 [PATCH 0/3] staging: rtl8723bs: fix OOB reads and heap overflow in IE parsing Alexandru Hossu
` (2 preceding siblings ...)
2026-04-24 15:19 ` [PATCH 3/3] staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie() Alexandru Hossu
@ 2026-04-24 16:05 ` Luka Gejak
3 siblings, 0 replies; 7+ messages in thread
From: Luka Gejak @ 2026-04-24 16:05 UTC (permalink / raw)
To: Alexandru Hossu, gregkh; +Cc: linux-staging
On Fri Apr 24, 2026 at 5:19 PM CEST, Alexandru Hossu wrote:
> This series fixes three related bugs in the rtl8723bs staging driver's
> 802.11 IE parsing code. All three follow the same root cause: IE parsing
> loops and IE handler functions do not validate that an IE's declared length
> fits within the actual frame/buffer before operating on it.
>
> Patch 1 and 2 fix OOB reads in three IE parsing loops
> (update_beacon_info, issue_assocreq, join_cmd_hdl) that lack the two-guard
> pattern already applied to OnAssocRsp() in a previous fix. A malicious AP
> sending a beacon or association response with a truncated final IE (e.g.,
> only the element_id byte present, no length byte) causes the loop to read
> pIE->length one byte past the end of the IE area.
>
> Patch 3 fixes a one-byte heap buffer overflow in rtw_cfg80211_set_wpa_ie().
> supplicant_ie is a 256-byte array in struct security_priv. Because
> wpa_ielen is taken directly from the IE length field (u8, 0-255), the copy:
>
> memcpy(supplicant_ie, pwpa, wpa_ielen + 2);
>
> can write up to 257 bytes. rtw_parse_wpa_ie()'s own length consistency
> check silently passes because it casts the arithmetic to u8:
> (u8)(257 - 2) == 255 == wpa_ielen. The overflow is triggered via
> NL80211_CMD_CONNECT with a crafted WPA IE of length 255; nl80211's
> validate_ie_attr() accepts this as a well-formed (though oversized) IE.
>
> 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 | 4 ++++
> drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 8 ++++++++
> 3 files changed, 20 insertions(+)
LGTM so for the patch series:
Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 7+ messages in thread