From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793209307; b=fnw9dC/LGyGfB8dwMWo/k81laM0HuyH2/Ch3J4HOjss1saZDLXykfSG1ZVn4CTHBkT1L beB0h+kkU3I45b/DKO0mAMf64yp030XUf3rycO1I8agnOboHYiAkFUU9eAd5UJR1C2lR/ fNv7rnxR2pHOXKL8vJ+ayuytGopxoS6W1j72hVlx1qe5aKGKdE4gsapfTDuSgDY6Bei2o g6kHeI2msRvB06P3FZg8Ts9zc63MOu4t+ZBKe8q7SKjGcdKJQYm2JigE07CCuN/5bQ5du qckiYVrco+QmSY3g7opyFGvuNfuT93Hv+U2wV+3eJpcij1Gxg0T1GDB53zM2+oPBCVQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793209307; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=T9DUowpNYdRgAd9tcKGycFcTFZUYD0Qrl/nigXkxDQg=; b=hAiEsa04qCF8FLXXqk5BJESTv03z87bET6/pyliqVHI1UOHIJyab8TYFyFT0zM0W4WJV TlDPHK5riIBOlLh3qReGPO5PGXw6mVrXugXzwwIQMVTxxYjEvO4pOXqZYGChSLdzx7Rrd GcFIzwy1c/UGePMcPB3gimTGsFFWVJQw34Kl9hfsWL4sub7onQX6F6OVu/ZCC0xjZfOjb hg8TqO9qDrdH7iABcm88w1zdGXdmZxjI/DE9DFEButskYOQgnAbUV2evUHDLRi6Zf/pUL JBgQJ5zZpoMtzDTOfgPPisNvUeHb/PnSGSG6psBJt6Gpbya7YA0nMr/qXKVNu627+NQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=wC0Yn4ei; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32FC8606A31D; Wed, 28 Oct 2026 17:41:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=wC0Yn4ei Received: by smtp.kernel.org (Postfix) with ESMTPSA id 84FA81F01825; Wed, 28 Oct 2026 17:41:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1793209307; bh=T9DUowpNYdRgAd9tcKGycFcTFZUYD0Qrl/nigXkxDQg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=wC0Yn4eifEs6WHEixtSfl7FB4878BpSrkTFKRJO7BeezCUtvXOSRFblxY8MKcck9M xBmqoBNdfx7yXWRGVZtSe2soWpMYHvN2ZkbaeqV9b1CUSoiuA6lu45eCU/bV4sM0oy jx2BtkXBZZukDadLt2WZanURHdcG2k9W6uVlTtW0= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Michele Dionisio , Arend van Spriel , Johannes Berg , Sasha Levin Subject: [PATCH 5.10 372/516] wifi: brcmfmac: fix P2P device removal race in brcmf_detach() Date: Wed, 28 Oct 2026 17:58:44 +0100 Message-ID: <20261028170012.298816721@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261028170003.522232767@linuxfoundation.org> References: <20261028170003.522232767@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Michele Dionisio [ Upstream commit 08a3f02fea636e97a7422d1512f76dacdb5b0887 ] When the driver is removed while the user space process that created the P2P device (e.g. wpa_supplicant) is still exiting, the P2P device interface is removed twice and the kernel crashes. The two paths are: - wpa_supplicant, on exit, sends NL80211_CMD_DEL_INTERFACE for the P2P device. nl80211_del_interface() holds RTNL and the wiphy mutex and calls brcmf_p2p_del_vif(), which disables discovery and waits up to 1.5 s for BRCMF_E_IF_DEL. Then it calls brcmf_remove_interface(), which unregisters the wdev and frees the vif and the ifp. - brcmf_detach() sets the bus down, so BRCMF_E_IF_DEL never arrives, and calls brcmf_remove_interface(ifp, false) for the same ifp. brcmf_p2p_ifp_removed() reads ifp->vif and then blocks on rtnl_lock(). When brcmf_p2p_del_vif() releases RTNL, it calls cfg80211_unregister_wdev() on the wdev that was already unregistered and freed. The second list_del_rcu() of wdev->list faults on LIST_POISON2: brcmfmac: brcmf_p2p_del_vif delete P2P vif brcmfmac: brcmf_p2p_deinit_discovery enter brcmfmac: brcmf_p2p_del_vif P2P: GO_NEG_PHASE status cleared brcmfmac: brcmf_detach Enter brcmfmac: brcmf_bus_change_state 1 -> 0 brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed [1.5 s later, brcmf_p2p_del_vif() timed out] brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0 brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed Unable to handle kernel paging request at virtual address dead000000000122 Internal error: Oops: 96000044 [#1] PREEMPT_RT SMP pc : _cfg80211_unregister_wdev+0x6c/0x264 [cfg80211] Call trace: _cfg80211_unregister_wdev+0x6c/0x264 [cfg80211] cfg80211_unregister_wdev+0x10/0x1c [cfg80211] brcmf_p2p_ifp_removed+0x84/0xb0 [brcmfmac] brcmf_remove_interface+0x1f4/0x254 [brcmfmac] brcmf_detach+0x88/0x180 [brcmfmac] brcmf_sdio_remove+0x90/0x7b0 [brcmfmac] brcmf_sdiod_remove+0x20/0xa0 [brcmfmac] brcmf_ops_sdio_remove+0xbc/0x12c [brcmfmac] sdio_bus_remove+0x38/0x144 device_release_driver_internal+0x1e8/0x2c0 device_release_driver+0x14/0x20 brcmf_sdio_bus_remove+0x2c/0x40 [brcmfmac] brcmf_fwvid_unregister_vendor+0xd8/0x170 [brcmfmac] __exit_compat+0x18/0x418 [brcmfmac_cyw] __arm64_sys_delete_module+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 wpa_supplicant on wlan0 and let it associate. It creates the P2P device (iw dev shows "type P2P-device"). 2. Stop wpa_supplicant and remove the driver without waiting for wpa_supplicant to exit: kill $(pidof wpa_supplicant) rmmod brcmfmac_cyw brcmfmac The crash is reproducible on that board. For the interface without a netdev (the P2P device), take RTNL and the wiphy mutex in brcmf_detach() before reading iflist, and remove it with locked=true. If brcmf_p2p_del_vif() runs first, brcmf_detach() finds the slot empty. If brcmf_detach() runs first, nl80211 does not find the wdev any more. The interfaces with a netdev are removed as before, because brcmf_del_if() takes RTNL on its own for the primary interface. Fixes: 9831bcb987df ("brcmfmac: Deleting of p2p device is leaking memory.") Cc: stable@vger.kernel.org Assisted-by: claude-opus-5-5 Signed-off-by: Michele Dionisio Acked-by: Arend van Spriel Link: https://patch.msgid.link/20260924123027.4122909-2-michele.dionisio@gmail.com Signed-off-by: Johannes Berg [ sashal: Removed unavailable wiphy_lock() and wiphy_unlock() calls to rely solely on RTNL locking. ] Signed-off-by: Sasha Levin --- .../broadcom/brcm80211/brcmfmac/core.c | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index b763495317f6c..309799d9ca433 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -1476,8 +1476,29 @@ void brcmf_detach(struct device *dev) brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); /* make sure primary interface removed last */ for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { - if (drvr->iflist[i]) - brcmf_remove_interface(drvr->iflist[i], false); + struct brcmf_if *ifp = drvr->iflist[i]; + + if (!ifp) + continue; + + if (ifp->ndev) { + brcmf_remove_interface(ifp, false); + continue; + } + + /* The P2P device interface has no netdev. Its removal can + * race with NL80211_CMD_DEL_INTERFACE issued by a user space + * process that is exiting (e.g. wpa_supplicant), which ends + * in brcmf_p2p_del_vif() under RTNL. If + * both paths remove the interface, the wdev is unregistered + * twice and the vif is used after being freed. Take the same + * lock and re-read iflist, so only one path removes it. + */ + rtnl_lock(); + ifp = drvr->iflist[i]; + if (ifp) + brcmf_remove_interface(ifp, true); + rtnl_unlock(); } brcmf_bus_stop(drvr->bus_if); -- 2.53.0