[PATCH 0/4] wifi: brcmfmac: Fix bugs when the device is removed before firmware is loaded
From: Sean Anderson
Date: Mon Sep 21 2026 - 17:18:28 EST
I was working on a different bug, and I noticed that brcmfmac tends to
crash quite spectacularly when the device gets removed before the
firmware request completes. This is because brcmfmac does quite a lot of
initialization that would be normally be done in probe() only when the
firmware is loaded. I found two general classes of bugs:
- Some of the remove paths try to clean up things that the firmware
request callback sets up, which doesn't work too well if the firmware
isn't loaded (patches 1 and 2).
- The firmware request callback generally assumes that the driver is
still alive and kicking. So if it runs after the driver is removed it
will procede to access all sorts of memory after it's been free'd.
A fairly-reliable way to trigger these bugs is to edit really_probe in
drivers/base/dd.c and replace
IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE)
with
!strcmp("brcmfmac", drv->name)
Alternatively, you can use the name of the bus's driver.
I have only tested these fixes on SDIO. I would really appreciate if
someone could test this series on PCIe with the above snippet in their
kernel (preferably with KASAN).
Right now if the firmware cannot be loaded for whatever reason then the
firmware request callback will unbind the driver. This is incompatible
with canceling the firmware request and waiting for it to complete in
the driver's remove() callback. As such, I removed this behavior so the
device now sticks around even if we can't load the firmware. If this
behavior is really, truly desired then we can drop device_lock while
waiting for the firmware request to complete and attempt to recover from
the consequences.
Sean Anderson (4):
wifi: brcmfmac: Fix canceling uninitialized datawork
wifi: brcmfmac: Fix brcmf_pno_detach NULL-pointer deference
firmware_loader: Return status from request_firmware_nowait_cancel
wifi: brcmfmac: Fix firmware requests racing against SDIO removal
drivers/base/firmware_loader/main.c | 11 +++++---
.../broadcom/brcm80211/brcmfmac/bcmsdh.c | 7 ++++-
.../broadcom/brcm80211/brcmfmac/bus.h | 2 ++
.../broadcom/brcm80211/brcmfmac/core.c | 3 +--
.../broadcom/brcm80211/brcmfmac/firmware.c | 26 ++++++++++++++++---
.../broadcom/brcm80211/brcmfmac/firmware.h | 16 +++++++++++-
.../broadcom/brcm80211/brcmfmac/pcie.c | 11 +++++---
.../broadcom/brcm80211/brcmfmac/pno.c | 2 ++
.../broadcom/brcm80211/brcmfmac/sdio.c | 8 +++---
.../broadcom/brcm80211/brcmfmac/usb.c | 6 +++--
include/linux/firmware.h | 2 +-
11 files changed, 75 insertions(+), 19 deletions(-)
---
base-commit: 587858367581b9c55c3690f4e63382ad622719d4
branch: brcmfmac_firmware_cancel
--
2.53.0