wifi: virt_wifi: don't transfer operstate before register

virt_wifi_newlink() calls netif_stacked_transfer_operstate() before
register_netdevice(). If the lower device is dormant, that queues the
new netdev on lweventlist while it is still uninitialized. If
registration fails after that, for example because of an invalid name
such as "bad/name", free_netdev() immediately frees the object. A
later linkwatch_fire_event() then use-after-frees the list entry.

Move the transfer to after netdev_upper_dev_link(), as macvlan and
ipvlan already do.

Fixes: c7cdba31ed ("mac80211-next: rtnetlink wifi simulation device")
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Link: https://patch.msgid.link/f5a832fb0ab228ce6e2b5a91fba4ca8b79198a2f.1788948455.git.zihanx@nebusec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Zihan Xi 2026-09-09 12:37:18 +00:00 committed by Johannes Berg
parent a842cfc1d6
commit e5c8d7acd3

View File

@ -558,7 +558,6 @@ static int virt_wifi_newlink(struct net_device *dev,
}
eth_hw_addr_inherit(dev, priv->lowerdev);
netif_stacked_transfer_operstate(priv->lowerdev, dev);
dev->ieee80211_ptr = kzalloc_obj(*dev->ieee80211_ptr);
@ -584,6 +583,8 @@ static int virt_wifi_newlink(struct net_device *dev,
goto unregister_netdev;
}
netif_stacked_transfer_operstate(priv->lowerdev, dev);
dev->priv_destructor = virt_wifi_net_device_destructor;
priv->being_deleted = false;
priv->is_connected = false;