[PATCH v1] nl80211: Unregister nl_mgmt within nl80211_pd_stop

Emily Xia xiayucheng at google.com
Mon Sep 28 06:23:15 PDT 2026


The PD nl_mgmt is not disconnected from the eloop which causes
an occasional use-after-free issue. If nl_mgmt is not released
after pd_stop is called, then the process_bss_event() callback can be
triggered against the freed struct i802_bss.

Detach drv->pd_bss first during nl80211_pd_stop() so incoming events
do not pick it up during teardown, unsubscribe nl_mgmt, and invoke
nl80211_destroy_bss() before freeing pd_bss. Also add the missing
nl80211_destroy_bss() call to the nl80211_pd_start() error cleanup path.

Signed-off-by: Emily Xia <xiayucheng at google.com>
---
 src/drivers/driver_nl80211.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a3c948cdc..de3e39401 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -16337,6 +16337,7 @@ failed_stop:
 	nl80211_set_pr_dev(pd_bss, 0);
 failed:
 	nl80211_del_non_netdev(pd_bss);
+	nl80211_destroy_bss(pd_bss);
 	os_free(pd_bss);
 	return -1;
 }
@@ -16349,20 +16350,29 @@ static void nl80211_pd_stop(void *priv)
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct i802_bss *pd_bss = drv->pd_bss;
 
-	if (!drv->pd_bss)
+	if (!pd_bss)
 		return;
 
 	wpa_printf(MSG_DEBUG,
 		   "nl80211: Stopping PD wdev wdev_id=0x%llx addr=" MACSTR,
-		   (unsigned long long) drv->pd_bss->wdev_id,
-		   MAC2STR(drv->pd_bss->addr));
+		   (unsigned long long) pd_bss->wdev_id,
+		   MAC2STR(pd_bss->addr));
 
-	nl80211_set_pr_dev(drv->pd_bss, 0);
-	nl80211_destroy_bss(drv->pd_bss);
-	nl80211_del_non_netdev(drv->pd_bss);
-	os_free(drv->pd_bss);
+	/*
+	 * Detach the PD BSS from the driver first so that no event or command
+	 * routing path (nl80211_get_event_bss(), send_mlme(), set_key(),
+	 * start_peer_measurement()) can pick it up while it is being torn
+	 * down.
+	 */
 	drv->pd_bss = NULL;
+
+	nl80211_mgmt_unsubscribe(pd_bss, "PD wdev stop");
+	nl80211_set_pr_dev(pd_bss, 0);
+	nl80211_del_non_netdev(pd_bss);
+	nl80211_destroy_bss(pd_bss);
+	os_free(pd_bss);
 }
 
 
-- 
2.56.0.rc1.315.gc6ed9934b7-goog




More information about the Hostap mailing list