All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths
@ 2026-07-14 16:35 Cong Nguyen
  2026-07-15 10:34 ` Dan Carpenter
  2026-07-15 11:17 ` [PATCH v2] " Cong Nguyen
  0 siblings, 2 replies; 3+ messages in thread
From: Cong Nguyen @ 2026-07-14 16:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Dan Carpenter, linux-staging, linux-kernel, Cong Nguyen

issue_beacon(), issue_probersp() and issue_asocrsp() obtain a management
xmit_frame together with its xmit_buf from the driver's fixed-size
management-TX pools via alloc_mgtxmitframe(). On the normal path the frame
is handed to dump_mgntframe(), which transfers ownership and eventually
returns both objects to their pools (the frame and, for beacons, the buf
in rtl8723bs_mgnt_xmit(); other bufs via the pending-xmitbuf/TX-completion
path).

Several error/edge paths return early after a successful
alloc_mgtxmitframe() but before dump_mgntframe(), so ownership is never
transferred and neither object is freed:

  - issue_beacon(): beacon larger than 512 bytes
  - issue_probersp(): cur_network->ie_length > MAX_IE_SZ
  - issue_probersp(): kzalloc() of the SSID scratch buffer fails
  - issue_asocrsp(): pkt_type is neither ASSOCRSP nor REASSOCRSP

Because alloc_mgtxmitframe() removes the frame and buf from their free
lists (list_del_init) without placing them on any pending list, an
orphaned pair is on no list and referenced by nobody, so it is only
reclaimed at driver teardown. Repeated hits progressively exhaust the
management-TX pools until alloc_mgtxmitframe() returns NULL and the
interface can no longer send beacons or probe/assoc responses.

Free the frame and buffer on these paths, matching the existing correct
error handling in issue_assocreq().

Signed-off-by: Cong Nguyen <congnt264@gmail.com>
---
 drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 22 ++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 8cf3c14a0dd7..354acd7ceb6f 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -2196,8 +2196,11 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
 
 	spin_unlock_bh(&pmlmepriv->bcn_update_lock);
 
-	if ((pattrib->pktlen + TXDESC_SIZE) > 512)
+	if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
+		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+		rtw_free_xmitframe(pxmitpriv, pmgntframe);
 		return;
+	}
 
 	pattrib->last_txcmdsz = pattrib->pktlen;
 
@@ -2258,8 +2261,11 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
 	pattrib->pktlen = pattrib->hdrlen;
 	pframe += pattrib->hdrlen;
 
-	if (cur_network->ie_length > MAX_IE_SZ)
+	if (cur_network->ie_length > MAX_IE_SZ) {
+		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+		rtw_free_xmitframe(pxmitpriv, pmgntframe);
 		return;
+	}
 
 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
 		pwps_ie = rtw_get_wps_ie(cur_network->ies + _FIXED_IE_LENGTH_,
@@ -2309,8 +2315,11 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
 				sizeof(struct ieee80211_hdr_3addr);
 
 			buf = kzalloc(MAX_IE_SZ, GFP_ATOMIC);
-			if (!buf)
+			if (!buf) {
+				rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+				rtw_free_xmitframe(pxmitpriv, pmgntframe);
 				return;
+			}
 
 			ssid_ie = rtw_get_ie(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID, &ssid_ielen,
 					     (pframe - ies) - _FIXED_IE_LENGTH_);
@@ -2689,10 +2698,13 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
-	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
+	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) {
 		SetFrameSubType(pwlanhdr, pkt_type);
-	else
+	} else {
+		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+		rtw_free_xmitframe(pxmitpriv, pmgntframe);
 		return;
+	}
 
 	pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
 	pattrib->pktlen += pattrib->hdrlen;
-- 
2.25.1


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

* Re: [PATCH] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths
  2026-07-14 16:35 [PATCH] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths Cong Nguyen
@ 2026-07-15 10:34 ` Dan Carpenter
  2026-07-15 11:17 ` [PATCH v2] " Cong Nguyen
  1 sibling, 0 replies; 3+ messages in thread
From: Dan Carpenter @ 2026-07-15 10:34 UTC (permalink / raw)
  To: Cong Nguyen; +Cc: Greg Kroah-Hartman, linux-staging, linux-kernel

On Tue, Jul 14, 2026 at 11:35:25PM +0700, Cong Nguyen wrote:
> issue_beacon(), issue_probersp() and issue_asocrsp() obtain a management
> xmit_frame together with its xmit_buf from the driver's fixed-size
> management-TX pools via alloc_mgtxmitframe(). On the normal path the frame
> is handed to dump_mgntframe(), which transfers ownership and eventually
> returns both objects to their pools (the frame and, for beacons, the buf
> in rtl8723bs_mgnt_xmit(); other bufs via the pending-xmitbuf/TX-completion
> path).
> 
> Several error/edge paths return early after a successful
> alloc_mgtxmitframe() but before dump_mgntframe(), so ownership is never
> transferred and neither object is freed:
> 
>   - issue_beacon(): beacon larger than 512 bytes
>   - issue_probersp(): cur_network->ie_length > MAX_IE_SZ
>   - issue_probersp(): kzalloc() of the SSID scratch buffer fails
>   - issue_asocrsp(): pkt_type is neither ASSOCRSP nor REASSOCRSP
> 
> Because alloc_mgtxmitframe() removes the frame and buf from their free
> lists (list_del_init) without placing them on any pending list, an
> orphaned pair is on no list and referenced by nobody, so it is only
> reclaimed at driver teardown. Repeated hits progressively exhaust the
> management-TX pools until alloc_mgtxmitframe() returns NULL and the
> interface can no longer send beacons or probe/assoc responses.
> 
> Free the frame and buffer on these paths, matching the existing correct
> error handling in issue_assocreq().
> 
> Signed-off-by: Cong Nguyen <congnt264@gmail.com>
> ---

Looks reasonable.  Please add a Fixes tag.

Reviewed-by: Dan Carpenter <error27@gmail.com>

regards,
dan carpenter


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

* [PATCH v2] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths
  2026-07-14 16:35 [PATCH] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths Cong Nguyen
  2026-07-15 10:34 ` Dan Carpenter
@ 2026-07-15 11:17 ` Cong Nguyen
  1 sibling, 0 replies; 3+ messages in thread
From: Cong Nguyen @ 2026-07-15 11:17 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Dan Carpenter, linux-staging, linux-kernel, Cong Nguyen

issue_beacon(), issue_probersp() and issue_asocrsp() obtain a management
xmit_frame together with its xmit_buf from the driver's fixed-size
management-TX pools via alloc_mgtxmitframe(). On the normal path the frame
is handed to dump_mgntframe(), which transfers ownership and eventually
returns both objects to their pools (the frame and, for beacons, the buf
in rtl8723bs_mgnt_xmit(); other bufs via the pending-xmitbuf/TX-completion
path).

Several error/edge paths return early after a successful
alloc_mgtxmitframe() but before dump_mgntframe(), so ownership is never
transferred and neither object is freed:

  - issue_beacon(): beacon larger than 512 bytes
  - issue_probersp(): cur_network->ie_length > MAX_IE_SZ
  - issue_probersp(): kzalloc() of the SSID scratch buffer fails
  - issue_asocrsp(): pkt_type is neither ASSOCRSP nor REASSOCRSP

Because alloc_mgtxmitframe() removes the frame and buf from their free
lists (list_del_init) without placing them on any pending list, an
orphaned pair is on no list and referenced by nobody, so it is only
reclaimed at driver teardown. Repeated hits progressively exhaust the
management-TX pools until alloc_mgtxmitframe() returns NULL and the
interface can no longer send beacons or probe/assoc responses.

Free the frame and buffer on these paths, matching the existing correct
error handling in issue_assocreq().

Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Reviewed-by: Dan Carpenter <error27@gmail.com>
---
v2:
 - Add Fixes tag (Dan Carpenter)

 drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 22 ++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 8cf3c14a0dd7..354acd7ceb6f 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -2196,8 +2196,11 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
 
 	spin_unlock_bh(&pmlmepriv->bcn_update_lock);
 
-	if ((pattrib->pktlen + TXDESC_SIZE) > 512)
+	if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
+		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+		rtw_free_xmitframe(pxmitpriv, pmgntframe);
 		return;
+	}
 
 	pattrib->last_txcmdsz = pattrib->pktlen;
 
@@ -2258,8 +2261,11 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
 	pattrib->pktlen = pattrib->hdrlen;
 	pframe += pattrib->hdrlen;
 
-	if (cur_network->ie_length > MAX_IE_SZ)
+	if (cur_network->ie_length > MAX_IE_SZ) {
+		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+		rtw_free_xmitframe(pxmitpriv, pmgntframe);
 		return;
+	}
 
 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
 		pwps_ie = rtw_get_wps_ie(cur_network->ies + _FIXED_IE_LENGTH_,
@@ -2309,8 +2315,11 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
 				sizeof(struct ieee80211_hdr_3addr);
 
 			buf = kzalloc(MAX_IE_SZ, GFP_ATOMIC);
-			if (!buf)
+			if (!buf) {
+				rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+				rtw_free_xmitframe(pxmitpriv, pmgntframe);
 				return;
+			}
 
 			ssid_ie = rtw_get_ie(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID, &ssid_ielen,
 					     (pframe - ies) - _FIXED_IE_LENGTH_);
@@ -2689,10 +2698,13 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
-	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
+	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) {
 		SetFrameSubType(pwlanhdr, pkt_type);
-	else
+	} else {
+		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+		rtw_free_xmitframe(pxmitpriv, pmgntframe);
 		return;
+	}
 
 	pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
 	pattrib->pktlen += pattrib->hdrlen;
-- 
2.25.1


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

end of thread, other threads:[~2026-07-15 11:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14 16:35 [PATCH] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths Cong Nguyen
2026-07-15 10:34 ` Dan Carpenter
2026-07-15 11:17 ` [PATCH v2] " Cong Nguyen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.