* [PATCH] wifi: nl80211: serialize socket owner release with netdev teardown
@ 2026-06-19 16:25 Cen Zhang
2026-07-06 11:42 ` Johannes Berg
0 siblings, 1 reply; 5+ messages in thread
From: Cen Zhang @ 2026-06-19 16:25 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel, baijiaju1990, zzzccc427
nl80211_netlink_notify() walks the cfg80211 wireless device list when a
NETLINK_GENERIC socket is released. If the socket owns a connection, the
notifier queues the embedded wdev->disconnect_wk work item.
NETDEV_GOING_DOWN tears the interface down and cancels disconnect_wk, and
NETDEV_UNREGISTER removes the wireless device from the cfg80211 list. There
is no ordering between those paths today, so the netlink notifier can pass
the conn_owner_nlportid check before teardown clears it, then queue
disconnect_wk after the NETDEV_GOING_DOWN cancel has already returned.
synchronize_net() only waits for the notifier to finish; it does not drain
the work that the notifier just queued.
The buggy scenario involves two paths, with each column showing the order
within that path:
NETLINK_URELEASE path: netdev teardown path:
1. enter nl80211_netlink_notify() 1. run NETDEV_GOING_DOWN
2. match conn_owner_nlportid 2. clear connection owner state
3. get preempted before scheduling 3. cancel disconnect_wk
4. schedule disconnect_wk 4. unregister and free the netdev
Take RTNL while the notifier walks cfg80211 devices and schedules owner
cleanup work. Netdevice notifier delivery already runs under RTNL, so the
schedule and cancel are ordered: either the work is queued before
NETDEV_GOING_DOWN and the existing cancel drains it, or teardown runs first
and the notifier no longer queues work for that connection owner.
Validation reproduced this kernel report:
BUG: KASAN: use-after-free in cfg80211_autodisconnect_wk+0x338/0x3a0
Workqueue: events cfg80211_autodisconnect_wk [cfg80211]
Read of size 8
Call trace:
dump_stack_lvl+0x66/0xa0
print_report+0xce/0x630
cfg80211_autodisconnect_wk+0x338/0x3a0
srso_alias_return_thunk+0x5/0xfbef5
__virt_addr_valid+0x224/0x430
kasan_report+0xac/0xe0
process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
lock_is_held_type+0x8f/0x100
worker_thread+0x5ad/0xfd0
__kthread_parkme+0xc6/0x200
kthread+0x31e/0x410
trace_hardirqs_on+0x1a/0x170
ret_from_fork+0x576/0x810
__switch_to+0x57e/0xe20
__switch_to_asm+0x33/0x70
ret_from_fork_asm+0x1a/0x30
Fixes: bd2522b16884 ("cfg80211: NL80211_ATTR_SOCKET_OWNER support for CMD_CONNECT")
Assisted-by: Codex:gpt-5.5
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
net/wireless/nl80211.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 53b4b3f76697..1e30673d1e79 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -22920,6 +22920,11 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
return NOTIFY_DONE;
+ /*
+ * Keep disconnect_wk scheduling ordered with NETDEV_GOING_DOWN's
+ * cancel_work_sync() and NETDEV_UNREGISTER's wdev list removal.
+ */
+ rtnl_lock();
rcu_read_lock();
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
@@ -22961,6 +22966,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
}
rcu_read_unlock();
+ rtnl_unlock();
/*
* It is possible that the user space process that is controlling the
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] wifi: nl80211: serialize socket owner release with netdev teardown
2026-06-19 16:25 [PATCH] wifi: nl80211: serialize socket owner release with netdev teardown Cen Zhang
@ 2026-07-06 11:42 ` Johannes Berg
2026-07-06 12:24 ` Cen Zhang
0 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2026-07-06 11:42 UTC (permalink / raw)
To: Cen Zhang; +Cc: linux-wireless, linux-kernel, baijiaju1990
On Sat, 2026-06-20 at 00:25 +0800, Cen Zhang wrote:
> NETDEV_GOING_DOWN tears the interface down and cancels disconnect_wk, and
> NETDEV_UNREGISTER removes the wireless device from the cfg80211 list. There
> is no ordering between those paths today,
What's that supposed to mean? Of course there's ordering between those
two things?
> so the netlink notifier can pass
> the conn_owner_nlportid check before teardown clears it, then queue
> disconnect_wk after the NETDEV_GOING_DOWN cancel has already returned.
Yeah I guess that seems like it could happen.
> Take RTNL while the notifier walks cfg80211 devices and schedules owner
> cleanup work. Netdevice notifier delivery already runs under RTNL, so the
> schedule and cancel are ordered: either the work is queued before
> NETDEV_GOING_DOWN and the existing cancel drains it, or teardown runs first
> and the notifier no longer queues work for that connection owner.
That seems a bit over the top vs. just moving the cancel - why is this
the only correct fix?
johannes
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] wifi: nl80211: serialize socket owner release with netdev teardown
2026-07-06 11:42 ` Johannes Berg
@ 2026-07-06 12:24 ` Cen Zhang
2026-07-06 14:34 ` Johannes Berg
0 siblings, 1 reply; 5+ messages in thread
From: Cen Zhang @ 2026-07-06 12:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel, baijiaju1990
Hi Johannes,
Thanks for your review and comments.
> What's that supposed to mean? Of course there's ordering between those
> two things?
You're right, that wording was imprecise.
I didn't mean that NETDEV_GOING_DOWN and NETDEV_UNREGISTER are unordered with
respect to each other. What I meant is that the NETLINK_URELEASE notifier's
schedule_work() site is not ordered against the teardown-side
cancel_work_sync() for the same wdev.
> Yeah I guess that seems like it could happen.
Yes, that is the race I was trying to describe:
notifier observes conn_owner_nlportid
teardown clears the connection state and cancel_work_sync() returns
notifier then queues disconnect_wk
unregister/free can then happen before the queued work runs
> That seems a bit over the top vs. just moving the cancel - why is this
> the only correct fix?
Agreed, I should not have implied that RTNL is the only correct fix.
I chose RTNL because netdev notifier delivery is already serialized by RTNL,
so it orders the existing schedule_work() producer against the existing
cancel_work_sync() with a small change. But if you prefer moving the cancel,
I can rework v2 in that direction.
My only concern with simply moving a final cancel into
_cfg80211_unregister_wdev() is that this path is called with the wiphy mutex
held, while cfg80211_autodisconnect_wk() also takes the wiphy mutex. So I
think the final drain would need to happen after the RCU readers are gone,
but outside the wiphy lock and before the wdev/netdev lifetime can end.
Best regards,
Cen Zhang
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] wifi: nl80211: serialize socket owner release with netdev teardown
2026-07-06 12:24 ` Cen Zhang
@ 2026-07-06 14:34 ` Johannes Berg
2026-07-06 15:18 ` Cen Zhang
0 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2026-07-06 14:34 UTC (permalink / raw)
To: Cen Zhang; +Cc: linux-wireless, linux-kernel, baijiaju1990
On Mon, 2026-07-06 at 20:24 +0800, Cen Zhang wrote:
> Hi Johannes,
>
> Thanks for your review and comments.
>
> > What's that supposed to mean? Of course there's ordering between those
> > two things?
>
> You're right, that wording was imprecise.
>
> I didn't mean that NETDEV_GOING_DOWN and NETDEV_UNREGISTER are unordered with
> respect to each other. What I meant is that the NETLINK_URELEASE notifier's
> schedule_work() site is not ordered against the teardown-side
> cancel_work_sync() for the same wdev.
Yeah, fair.
> I chose RTNL because netdev notifier delivery is already serialized by RTNL,
> so it orders the existing schedule_work() producer against the existing
> cancel_work_sync() with a small change. But if you prefer moving the cancel,
> I can rework v2 in that direction.
>
> My only concern with simply moving a final cancel into
> _cfg80211_unregister_wdev() is that this path is called with the wiphy mutex
> held, while cfg80211_autodisconnect_wk() also takes the wiphy mutex. So I
> think the final drain would need to happen after the RCU readers are gone,
> but outside the wiphy lock and before the wdev/netdev lifetime can end.
Sounds like maybe it should just be a wiphy work so we don't have to
worry about the locking at all?
johannes
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-06 15:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-19 16:25 [PATCH] wifi: nl80211: serialize socket owner release with netdev teardown Cen Zhang
2026-07-06 11:42 ` Johannes Berg
2026-07-06 12:24 ` Cen Zhang
2026-07-06 14:34 ` Johannes Berg
2026-07-06 15:18 ` Cen Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox