bwn_intr_noise missing re-entry guard: 9th noise-sample interrupt writes 4 bytes past noi_samples into mac_phy
Summary
BWN_INTR_NOISESAMPLE_OK stays unmasked in BWN_INTR_MASKTEMPLATE after the 8-sample noise window closes. A stale/duplicate noise interrupt re-enters bwn_intr_noise, which has no runtime guard (entry guards are KASSERTs only, compiled out of production): i=noi_nsamples=8 and noi_samples[8][0..3] writes 4 bytes past the [8][4] array - into struct bwn_phy mac_phy (single kmalloc'd bwn_mac) - corrupting phy type/rev/analog with RSSI-LUT bytes. INVARIANTS kernels panic at KASSERT instead. Firmware-interrupt anomaly (same duplicate-reporting class the driver documents for TX-done) or malicious card on a G-PHY bwn device; realistic outcome is panic on stock kernels, silent intra-object PHY-struct corruption otherwise. Source-certain; guest hardware-absent.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3594 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 938 B | β raw | |
| VERDICT.md | β | 3.3 KB | β raw | |
| probe.sh | β | 838 B | view raw | |
| run.log | β | 581 B | view raw | |
| fix.diff | β | 679 B | view raw | |
| manifest.json | β | 1.1 KB | view raw | |
| verdict.json | β | 2.2 KB | view raw |
DF-3594 β bwn_intr_noise re-entry after sample collection completes β 4-byte OOB write past noi_samples into mac_phy (or KASSERT 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 (G-PHY) machine whose firmware raises an extra
BWN_INTR_NOISESAMPLE_OK after the 8-sample window closed (spurious/stale
interrupt, or a malicious card), the expected observation:
- INVARIANTS kernels:
panic: kassert "/sys/dev/netif/bwn/bwn/if_bwn.c:5198: fail" - non-INVARIANTS kernels: silent 4-byte out-of-bounds write at
mac->mac_noise.noi_samples[8][0..3]β past the[8][4]array intostruct bwn_phy mac_phy(if_bwnvar.h:576-580,:917-918) β corruptingmac_phy.type/rev/analogwith RSSI-LUT bytes influenced by the received signal, leading to subsequent misbehavior/panic in PHY dispatch.
VERDICT β DF-3594
Status: inconclusive at runtime (no bwn hardware on the audit guest); defect source-certain.
Impact: panic (INVARIANTS) / 4-byte intra-object OOB write into struct bwn_phy (non-INVARIANTS).
Root cause (path:line)
bwn_intr_noise() (sys/dev/netif/bwn/bwn/if_bwn.c:5181-5230) runs on every
BWN_INTR_NOISESAMPLE_OK:
- The noise-sampling state machine:
bwn_task_30s()(:6794-6804) setsnoi_running = 1; noi_nsamples = 0and requests a sample (bwn_noise_gensample :5409-5418). - Each interrupt appends:
i = mac->mac_noise.noi_nsamples;(:5200),mac->mac_noise.noi_samples[i][0..3] = β¦(:5205-5208),noi_nsamples++(:5209). When the count reaches 8 the driver computes the average and terminates sampling:noi_running = 0;(:5225) β but the sample-interrupt is never masked off:BWN_INTR_NOISESAMPLE_OKis part ofBWN_INTR_MASKTEMPLATE(sys/dev/netif/bwn/bwn/if_bwnreg.h:324-328, installed asmac_intr_maskatif_bwn.c:2137and re-enabled at the end of everybwn_intrtaskat:5023), andbwn_intrtaskinvokesbwn_intr_noise()whenever the bit is set (:4997-4998). - There is no
noi_running/noi_nsamples < 8runtime guard at function entry (:5189-5200): onlyKASSERT(mac->mac_noise.noi_running)(:5192) andKASSERT(noi_nsamples < 8)(:5198-5199), which are compiled out of non-INVARIANTS kernels and are panics rather than guards on INVARIANTS ones. - A ninth invocation (stale/spurious firmware interrupt β same
duplicate-reporting behavior the driver documents for TX-done at
:7088-7091, or a malicious card raising the bit) withnoi_nsamples == 8executesnoi_samples[8][j] =(:5205-5208).
struct bwn_noise ends with int8_t noi_samples[8][4]
(sys/dev/netif/bwn/bwn/if_bwnvar.h:576-580) and is immediately followed by
struct bwn_phy mac_phy inside struct bwn_mac (if_bwnvar.h:917-918) β the
mac object is a single kmalloc(sizeof(*mac)) (if_bwn.c:586). The write
lands on mac_phy.type/rev/analog (if_bwnvar.h:442-445) with values
pg_nrssi_lt[clamped rssi byte] β firmware-controlled, RF-influenced data.
PHY type corruption feeds later dispatch (bwn_rate_init :2402, bwn_set_opmode,
PHY op pointer selection at attach is already done β so this mostly yields
wrong-code-path panics rather than a controlled hijack; honest impact:
kernel-memory corruption with limited control, realistic outcome panic).
Why runtime reproduction was not possible
Same as DF-3593: virtio-only guest, no BCM43xx card (run.log). The G-PHY
noise-sample interrupt cannot be raised. No uid0 chain β the write offset is
fixed (+32 bytes into mac_phy) and the value domain is a 64-entry RSSI LUT.
Fix
Early-return unless the state machine expects a sample β 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 incl. struct layout adjacency; run.log guest probe; fix.diff adds noi_running/nsamples entry guard
PoC changes
No runnable PoC possible without hardware; probe.sh substitutes
Verified recommended fix
Early-return in bwn_intr_noise unless noi_running && noi_nsamples < 8
Verdict
Source-certain missing guard in bwn_intr_noise (if_bwn.c:5189-5209): NOISESAMPLE_OK stays unmasked in BWN_INTR_MASKTEMPLATE (if_bwnreg.h:324-328) after the 8-sample window closes (noi_running=0 at if_bwn.c:5225), so a 9th/stale firmware noise interrupt indexes noi_samples[8] β a 4-byte OOB write into the adjacent struct bwn_phy within the kmalloc'd bwn_mac (if_bwnvar.h:576-580, 917-918). INVARIANTS kernels (stock DF) panic at KASSERT if_bwn.c:5198 instead. Guest has no Broadcom 802.11 device (run.log) so runtime trigger impossible; trigger class = duplicate/stale device interrupt, the same firmware behavior the driver documents for TX-done (if_bwn.c:7088-7091) or a malicious card.
No comments yet.