CVE-2026-99061: wifi: brcmfmac: fix P2P device removal race in brcmf_detach()
In the Linux kernel, the following vulnerability has been resolved:
wifi: brcmfmac: fix P2P device removal race in brcmfdetach()
When the driver is removed while the user space process that created the P2P device (e.g. wpasupplicant) is still exiting, the P2P device interface is removed twice and the kernel crashes.
The two paths are:
- wpasupplicant, on exit, sends NL80211CMDDELINTERFACE for the P2P device. nl80211delinterface() holds RTNL and the wiphy mutex and calls brcmfp2pdelvif(), which disables discovery and waits up to 1.5 s for BRCMFEIFDEL. Then it calls brcmfremoveinterface(), which unregisters the wdev and frees the vif and the ifp.
- brcmfdetach() sets the bus down, so BRCMFEIFDEL never arrives, and calls brcmfremoveinterface(ifp, false) for the same ifp. brcmfp2pifpremoved() reads ifp->vif and then blocks on rtnllock(). When brcmfp2pdelvif() releases RTNL, it calls cfg80211unregisterwdev() on the wdev that was already unregistered and freed.
The second listdelrcu() of wdev->list faults on LISTPOISON2:
brcmfmac: brcmfp2pdelvif delete P2P vif brcmfmac: brcmfp2pdeinitdiscovery enter brcmfmac: brcmfp2pdelvif P2P: GONEGPHASE status cleared brcmfmac: brcmfdetach Enter brcmfmac: brcmfbuschangestate 1 -> 0 brcmfmac: brcmfremoveinterface Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmfdelif Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmfp2pifpremoved P2P: device interface removed [1.5 s later, brcmfp2pdelvif() timed out] brcmfmac: brcmfremoveinterface Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmfdelif Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmfp2pifpremoved P2P: device interface removed Unable to handle kernel paging request at virtual address dead000000000122 Internal error: Oops: 96000044 [#1] PREEMPTRT SMP pc : cfg80211unregisterwdev+0x6c/0x264 [cfg80211] Call trace: cfg80211unregisterwdev+0x6c/0x264 [cfg80211] cfg80211unregisterwdev+0x10/0x1c [cfg80211] brcmfp2pifpremoved+0x84/0xb0 [brcmfmac] brcmfremoveinterface+0x1f4/0x254 [brcmfmac] brcmfdetach+0x88/0x180 [brcmfmac] brcmfsdioremove+0x90/0x7b0 [brcmfmac] brcmfsdiodremove+0x20/0xa0 [brcmfmac] brcmfopssdioremove+0xbc/0x12c [brcmfmac] sdiobusremove+0x38/0x144 devicereleasedriverinternal+0x1e8/0x2c0 devicereleasedriver+0x14/0x20 brcmfsdiobusremove+0x2c/0x40 [brcmfmac] brcmffwvidunregistervendor+0xd8/0x170 [brcmfmac] exitcompat+0x18/0x418 [brcmfmaccyw] arm64sysdeletemodule+0x1ac/0x244
The log was taken with debug=0x406 on an i.MX 8M Plus board with a CYW55513 (Sona IF513) on SDIO. The driver is the Ezurio backport of brcmfmac from v6.18.22 on a 5.4-rt kernel. The code involved is the same in mainline.
To reproduce:
1. Start wpasupplicant on wlan0 and let it associate. It creates the P2P device (iw dev shows "type P2P-device"). 2. Stop wpasupplicant and remove the driver without waiting for wpasupplicant to exit:
kill $(pidof wpasupplicant) rmmod brcmfmaccyw brcmfmac
The crash is reproducible on that board.
For the interface without a netdev (the P2P device), take RTNL and the wiphy mutex in brcmfdetach() before reading iflist, and remove it with locked=true. If brcmfp2pdelvif() runs first, brcmfdetach() finds the slot empty. If brcmfdetach() runs first, nl80211 does not find the wdev any more. The interfaces with a netdev are removed as before, because brcmfdelif() takes RTNL on its own for the primary interface.