sc_curmac left NULL after failed band-switch/hw-reset while RUNNING: bwn_stop/bwn_detach/bwn_suspend NULL-deref panic
Summary
bwn_switch_band and bwn_hwreset set sc->sc_curmac=NULL when re-init fails, without clearing BWN_FLAG_RUNNING; callers of bwn_set_channel ignore the error. The next bwn_stop - from bwn_parent, bwn_suspend or bwn_detach - dereferences the NULL mac and panics. The TX path guards mac==NULL but stop/detach/suspend do not. Error-path reachable on any BCM43xx system (firmware re-load failure during channel change or device reset - e.g. firmware files removed after first bring-up, flaky or malicious card); not user-triggerable by RF alone. Source-certain; guest hardware-absent.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3595 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 762 B | β raw | |
| VERDICT.md | β | 2.9 KB | β raw | |
| probe.sh | β | 838 B | view raw | |
| run.log | β | 581 B | view raw | |
| fix.diff | β | 541 B | view raw | |
| manifest.json | β | 998 B | view raw | |
| verdict.json | β | 2.0 KB | view raw |
DF-3595 β sc_curmac left NULL after failed band-switch/hw-reset while RUNNING: bwn_stop/bwn_detach/bwn_suspend NULL-deref panic
Build / Run / Expected
# on the DF guest, as root: sh probe.sh
Guest result: driver resident, no Broadcom hardware β runtime inconclusive.
On a BCM43xx machine: bring the interface up (firmware loads OK, RUNNING set),
then force bwn_switch_band()/bwn_hwreset() to fail β e.g. make
bwn_core_init() fail on re-init (unload the bwn v4 firmware files after first
bring-up, or flaky/malicious card) β then ifconfig bwn0 down, devdetach, or
suspend: bwn_stop() dereferences sc->sc_curmac == NULL at
if_bwn.c:2048 β immediate kernel NULL-deref panic (mac->mac_status read at
address ~0x18).
VERDICT β DF-3595
Status: inconclusive at runtime (no bwn hardware on the audit guest); defect source-certain. Impact: kernel NULL-deref panic (local DoS) via error-path lifetime bug.
Root cause (path:line)
Two failure paths clear sc->sc_curmac to NULL without clearing
BWN_FLAG_RUNNING or otherwise quiescing the softc:
bwn_switch_band()β onbwn_core_init(up_dev)failure:fail: sc->sc_curmac = NULL; return (err);(sys/dev/netif/bwn/bwn/if_bwn.c:4763-4765).bwn_hwreset()β onbwn_core_init(mac)failure:sc->sc_curmac = NULL;(if_bwn.c:5363-5366).
In both cases the interface was previously up (bwn_init() set
BWN_FLAG_RUNNING at :2032; callers of bwn_set_channel ignore the
band-switch error β :1906-1908 only jumps to the radiotap tail β and
bwn_restart schedules hwreset from interrupt context at :5064).
Every subsequent state-changing entry point that trusts sc_curmac then
dereferences NULL:
bwn_stop():struct bwn_mac *mac = sc->sc_curmac;(:2042) β¦if (mac->mac_status >= BWN_MAC_STATUS_INITED)(:2048) β NULL deref. Reached frombwn_parent()(:910),bwn_suspend()(:7374), andbwn_detach()(:791-794β notebwn_detachalso fetchesmacat:783and callsbwn_dma_free(mac)at:795unconditionally for attached devices).- Contrast:
bwn_start()does check (mac == NULL ||at:949), andbwn_update_promisc/bwn_wme_updatere-fetch with NULL guards (:1827-1828,:1850-1851) β the author knewsc_curmaccan be NULL and guarded the TX/promisc paths but not stop/detach/suspend.
Reachability of the failure itself: bwn_core_init fails whenever firmware
re-load fails (bwn_fw_fillinfo β bwn_fw_get β firmware_get ENOENT,
if_bwn.c:2298), PMU/powerup issues, or PHY re-init errors β a realistic
field state on systems whose firmware files disappear after first load, or on
a malicious card that fails the second init deliberately. The error paths at
:4764/:5365 then arm the panic for the next ifconfig down/detach.
Why runtime reproduction was not possible
Same as DF-3593/3594: no Broadcom card on the guest (run.log). The
attachβinitβband-switch-failβstop sequence cannot be entered.
Fix
Treat curmac==NULL as already-down in bwn_stop() (and guard bwn_detach's
bwn_dma_free), or clear BWN_FLAG_RUNNING when nulled β see fix.diff.
Artifacts
probe.sh,run.logβ guest probe (driver residency + hardware absence)fix.diffβ proposed patch vs read-onlysys/tree (never applied)
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablefix.diff authored against read-only sys/; cannot baseline-validate without BCM43xx hardware
fix.diff in this pack
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md path:line trace; run.log guest probe; fix.diff adds NULL guard clearing RUNNING in bwn_stop
PoC changes
No runnable PoC possible without hardware; probe.sh substitutes
Verified recommended fix
NULL-guard sc_curmac in bwn_stop (clear BWN_FLAG_RUNNING and return)
Verdict
Source-certain error-path lifetime bug: bwn_switch_band (if_bwn.c:4764) and bwn_hwreset (if_bwn.c:5365) set sc->sc_curmac=NULL on re-init failure while BWN_FLAG_RUNNING stays set and callers ignore the error; the next bwn_stop (if_bwn.c:2048 β from bwn_parent :910, bwn_suspend :7374, bwn_detach :791-794) dereferences the NULL mac and panics. Driver already guards mac==NULL on the TX path (if_bwn.c:949) but not on stop/detach/suspend. Guest has no Broadcom device (run.log) so the upβband-switch-failβdown sequence cannot run; trigger requires fw re-load failure (missing firmware after first load, flaky or malicious card).
No comments yet.