public inbox for linux-staging@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH v3 0/5] staging: rtl8723bs: fix multiple missing bounds checks
@ 2026-04-05 10:15 Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 1/5] staging: rtl8723bs: fix heap buffer overflow in recvframe_defrag() Delene Tchio Romuald
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Delene Tchio Romuald @ 2026-04-05 10:15 UTC (permalink / raw)
  To: gregkh
  Cc: Ethan Tidmore, Sam Daly, linux-staging, linux-kernel,
	Delene Tchio Romuald

This series fixes five missing bounds checks in the rtl8723bs driver
that can be triggered by malformed WiFi frames. Each patch addresses
one function and is independent of the others, but they are sent as
a series since they all modify the same driver.

All patches are based on staging-next, pass checkpatch with no errors
or warnings, and compile cleanly. Found by reviewing the 40 memcpy
calls in rtw_recv.c and tracing buffer pointer manipulation through
the inline helpers in rtw_recv.h. Not tested on hardware.

Changes since v2:
 - Rebased on staging-next
 - Sent as a numbered series instead of individual patches
 - Added proper Cc list from get_maintainer.pl

Delene Tchio Romuald (5):
  staging: rtl8723bs: fix heap buffer overflow in recvframe_defrag()
  staging: rtl8723bs: fix integer underflow in TKIP MIC verification
  staging: rtl8723bs: fix out-of-bounds read in portctrl()
  staging: rtl8723bs: fix out-of-bounds reads in IE parsing functions
  staging: rtl8723bs: fix negative length in WEP decryption

 .../staging/rtl8723bs/core/rtw_ieee80211.c    | 15 +++++--
 drivers/staging/rtl8723bs/core/rtw_recv.c     | 43 ++++++++++++++-----
 drivers/staging/rtl8723bs/core/rtw_security.c |  6 +++
 3 files changed, 50 insertions(+), 14 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3 1/5] staging: rtl8723bs: fix heap buffer overflow in recvframe_defrag()
  2026-04-05 10:15 [PATCH v3 0/5] staging: rtl8723bs: fix multiple missing bounds checks Delene Tchio Romuald
@ 2026-04-05 10:15 ` Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 2/5] staging: rtl8723bs: fix integer underflow in TKIP MIC verification Delene Tchio Romuald
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Delene Tchio Romuald @ 2026-04-05 10:15 UTC (permalink / raw)
  To: gregkh
  Cc: Ethan Tidmore, Sam Daly, linux-staging, linux-kernel,
	Delene Tchio Romuald

In recvframe_defrag(), a memcpy() copies fragment data into the
reassembly buffer before recvframe_put() validates that the buffer
has sufficient space. If the total reassembled payload exceeds the
receive buffer capacity, this results in a heap buffer overflow.

An attacker within WiFi radio range can exploit this by sending
crafted 802.11 fragmented frames. No authentication is required.

Add a bounds check before the memcpy() to verify that the fragment
payload fits within the remaining buffer space, using the same error
handling pattern already present in the function.

Found by reviewing memory operations in the driver and tracing
buffer pointer manipulation through rtw_recv.h inline helpers.
Not tested on hardware.

Signed-off-by: Delene Tchio Romuald <delenetchior1@gmail.com>
---
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)
 - Removed Cc: stable (will be added by maintainer)

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

diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c
index f78194d508dfc..717e0594d983a 100644
--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
+++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
@@ -1132,7 +1132,13 @@ static union recv_frame *recvframe_defrag(struct adapter *adapter,
 		/* append  to first fragment frame's tail (if privacy frame, pull the ICV) */
 		recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
 
-		/* memcpy */
+		/* Verify the receiving buffer has enough space for the fragment */
+		if (pnfhdr->len > (uint)(pfhdr->rx_end - pfhdr->rx_tail)) {
+			rtw_free_recvframe(prframe, pfree_recv_queue);
+			rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
+			return NULL;
+		}
+
 		memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
 
 		recvframe_put(prframe, pnfhdr->len);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/5] staging: rtl8723bs: fix integer underflow in TKIP MIC verification
  2026-04-05 10:15 [PATCH v3 0/5] staging: rtl8723bs: fix multiple missing bounds checks Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 1/5] staging: rtl8723bs: fix heap buffer overflow in recvframe_defrag() Delene Tchio Romuald
@ 2026-04-05 10:15 ` Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 3/5] staging: rtl8723bs: fix out-of-bounds read in portctrl() Delene Tchio Romuald
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Delene Tchio Romuald @ 2026-04-05 10:15 UTC (permalink / raw)
  To: gregkh
  Cc: Ethan Tidmore, Sam Daly, linux-staging, linux-kernel,
	Delene Tchio Romuald

In recvframe_chkmic(), datalen is computed as:

  datalen = len - hdrlen - iv_len - icv_len - 8;

All operands are unsigned, so if the frame is shorter than the sum of
header, IV, ICV, and MIC lengths, the subtraction wraps to a very
large value. This corrupted datalen is then passed to
rtw_seccalctkipmic() and used as a pointer offset, leading to
out-of-bounds reads on kernel heap memory.

Add a minimum frame length check before the subtraction to prevent
the unsigned integer underflow.

Found by reviewing memory operations in the driver.
Not tested on hardware.

Signed-off-by: Delene Tchio Romuald <delenetchior1@gmail.com>
---
v3:
 - Rebased on staging-next
 - Sent as numbered series with proper Cc from get_maintainer.pl
v2:
 - Rebased on staging-next (v1 did not apply due to whitespace changes)

 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 717e0594d983a..11ae99e53b86a 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


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 3/5] staging: rtl8723bs: fix out-of-bounds read in portctrl()
  2026-04-05 10:15 [PATCH v3 0/5] staging: rtl8723bs: fix multiple missing bounds checks Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 1/5] staging: rtl8723bs: fix heap buffer overflow in recvframe_defrag() Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 2/5] staging: rtl8723bs: fix integer underflow in TKIP MIC verification Delene Tchio Romuald
@ 2026-04-05 10:15 ` Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 4/5] staging: rtl8723bs: fix out-of-bounds reads in IE parsing functions Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 5/5] staging: rtl8723bs: fix negative length in WEP decryption Delene Tchio Romuald
  4 siblings, 0 replies; 6+ messages in thread
From: Delene Tchio Romuald @ 2026-04-05 10:15 UTC (permalink / raw)
  To: gregkh
  Cc: Ethan Tidmore, Sam Daly, linux-staging, linux-kernel,
	Delene Tchio Romuald

In portctrl(), the pointer is advanced by hdrlen + iv_len +
LLC_HEADER_LENGTH and then 2 bytes are read via memcpy() to extract
the ether_type field. There is no check that the frame is large
enough to contain these fields, so a short frame leads to an
out-of-bounds read on kernel heap memory.

This code is reachable during 802.1X authentication when the station
is in the ieee8021x_blocked state.

Add a frame length check before the pointer arithmetic and wrap the
existing ether_type extraction in the else branch so that short
frames are dropped safely.

Found by reviewing memory operations in the driver.
Not tested on hardware.

Signed-off-by: Delene Tchio Romuald <delenetchior1@gmail.com>
---
v3:
 - Rebased on staging-next
 - Sent as numbered series with proper Cc from get_maintainer.pl
v2:
 - Rebased on staging-next

 drivers/staging/rtl8723bs/core/rtw_recv.c | 28 +++++++++++++++--------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c
index 11ae99e53b86a..8e38cb9791755 100644
--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
+++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
@@ -539,17 +539,25 @@ static union recv_frame *portctrl(struct adapter *adapter, union recv_frame *pre
 
 			prtnframe = precv_frame;
 
-			/* get ether_type */
-			ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_LENGTH;
-			memcpy(&be_tmp, ptr, 2);
-			ether_type = ntohs(be_tmp);
-
-			if (ether_type == eapol_type)
-				prtnframe = precv_frame;
-			else {
-				/* free this frame */
-				rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
+			/* Ensure frame has LLC header and ether_type */
+			if (pfhdr->len < pattrib->hdrlen +
+			    pattrib->iv_len + LLC_HEADER_LENGTH + 2) {
+				rtw_free_recvframe(precv_frame,
+						   &adapter->recvpriv.free_recv_queue);
 				prtnframe = NULL;
+			} else {
+				/* get ether_type */
+				ptr += pattrib->hdrlen +
+				       pattrib->iv_len +
+				       LLC_HEADER_LENGTH;
+				memcpy(&be_tmp, ptr, 2);
+				ether_type = ntohs(be_tmp);
+
+				if (ether_type != eapol_type) {
+					rtw_free_recvframe(precv_frame,
+							   &adapter->recvpriv.free_recv_queue);
+					prtnframe = NULL;
+				}
 			}
 		} else {
 			/* allowed */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 4/5] staging: rtl8723bs: fix out-of-bounds reads in IE parsing functions
  2026-04-05 10:15 [PATCH v3 0/5] staging: rtl8723bs: fix multiple missing bounds checks Delene Tchio Romuald
                   ` (2 preceding siblings ...)
  2026-04-05 10:15 ` [PATCH v3 3/5] staging: rtl8723bs: fix out-of-bounds read in portctrl() Delene Tchio Romuald
@ 2026-04-05 10:15 ` Delene Tchio Romuald
  2026-04-05 10:15 ` [PATCH v3 5/5] staging: rtl8723bs: fix negative length in WEP decryption Delene Tchio Romuald
  4 siblings, 0 replies; 6+ messages in thread
From: Delene Tchio Romuald @ 2026-04-05 10:15 UTC (permalink / raw)
  To: gregkh
  Cc: Ethan Tidmore, Sam Daly, linux-staging, linux-kernel,
	Delene Tchio Romuald

The IE parsing loops in rtw_get_wapi_ie(), rtw_get_sec_ie(), and
rtw_get_wps_ie() check only that the element ID byte is within bounds
(cnt < in_len), but then immediately access the length byte at
in_ie[cnt+1] and data bytes at in_ie[cnt+2] and beyond without
verifying that these offsets are within the buffer.

A malicious access point can send beacon or probe response frames with
truncated Information Elements, triggering out-of-bounds reads on
kernel heap memory. No authentication is required.

Add two bounds checks to each function:
 - Ensure at least 2 bytes remain for the IE header (cnt + 1 < in_len)
 - Validate the full IE fits in the buffer before accessing its data
   (cnt + 2 + ie_len <= in_len)

Found by reviewing memory operations in the driver.
Not tested on hardware.

Signed-off-by: Delene Tchio Romuald <delenetchior1@gmail.com>
---
v3:
 - Rebased on staging-next
 - Sent as numbered series with proper Cc from get_maintainer.pl
v2:
 - Rebased on staging-next (v1 did not apply due to code reformatting)

 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


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 5/5] staging: rtl8723bs: fix negative length in WEP decryption
  2026-04-05 10:15 [PATCH v3 0/5] staging: rtl8723bs: fix multiple missing bounds checks Delene Tchio Romuald
                   ` (3 preceding siblings ...)
  2026-04-05 10:15 ` [PATCH v3 4/5] staging: rtl8723bs: fix out-of-bounds reads in IE parsing functions Delene Tchio Romuald
@ 2026-04-05 10:15 ` Delene Tchio Romuald
  4 siblings, 0 replies; 6+ messages in thread
From: Delene Tchio Romuald @ 2026-04-05 10:15 UTC (permalink / raw)
  To: gregkh
  Cc: Ethan Tidmore, Sam Daly, linux-staging, linux-kernel,
	Delene Tchio Romuald

In rtw_wep_decrypt(), length is declared as signed int and computed as:

  length = len - hdrlen - iv_len;

If the received frame is shorter than the combined header and IV
lengths, length becomes negative. It is then passed to arc4_crypt()
which takes a u32 parameter, causing the negative value to be
implicitly cast to a very large unsigned value (e.g., -8 becomes
4294967288). This results in a massive out-of-bounds read and write
on the heap via arc4_crypt(), and a similar overflow at the
subsequent crc32_le() call using length - 4.

Add a minimum frame length check before the subtraction to ensure
length is always positive.

Found by reviewing memory operations in the driver.
Not tested on hardware.

Signed-off-by: Delene Tchio Romuald <delenetchior1@gmail.com>
---
v3:
 - Rebased on staging-next
 - Sent as numbered series with proper Cc from get_maintainer.pl

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

diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c
index a00504ff29109..f3bc2240749a4 100644
--- a/drivers/staging/rtl8723bs/core/rtw_security.c
+++ b/drivers/staging/rtl8723bs/core/rtw_security.c
@@ -113,6 +113,12 @@ void rtw_wep_decrypt(struct adapter  *padapter, u8 *precvframe)
 		memcpy(&wepkey[0], iv, 3);
 		/* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
 		memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
+
+		/* Ensure the frame is long enough for WEP decryption */
+		if (((union recv_frame *)precvframe)->u.hdr.len <=
+		    prxattrib->hdrlen + prxattrib->iv_len)
+			return;
+
 		length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;
 
 		payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-05 10:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-05 10:15 [PATCH v3 0/5] staging: rtl8723bs: fix multiple missing bounds checks Delene Tchio Romuald
2026-04-05 10:15 ` [PATCH v3 1/5] staging: rtl8723bs: fix heap buffer overflow in recvframe_defrag() Delene Tchio Romuald
2026-04-05 10:15 ` [PATCH v3 2/5] staging: rtl8723bs: fix integer underflow in TKIP MIC verification Delene Tchio Romuald
2026-04-05 10:15 ` [PATCH v3 3/5] staging: rtl8723bs: fix out-of-bounds read in portctrl() Delene Tchio Romuald
2026-04-05 10:15 ` [PATCH v3 4/5] staging: rtl8723bs: fix out-of-bounds reads in IE parsing functions Delene Tchio Romuald
2026-04-05 10:15 ` [PATCH v3 5/5] staging: rtl8723bs: fix negative length in WEP decryption Delene Tchio Romuald

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox