Inverted KASSERT in bwn_phy_lp_tblinit_r2 asserts rev < 2 although it is only ever called for rev >= 2 β deterministic panic at PHY init on INVARIANTS kernels (upstream-inherited)
Summary
bwn_phy_lp_tblinit dispatches r2 only when mac->mac_phy.rev >= 2 but bwn_phy_lp_tblinit_r2 opens with KASSERT(mac->mac_phy.rev < 2) - inverted vs its only caller and vs the driver's own companions. On any INVARIANTS kernel the assert fails unconditionally at first LP-rev>=2 PHY init. KASSERT is a no-op on stock GENERIC, and bwn is compiled into X86_64_GENERIC. FreeBSD head carries the identical inversion. Attach/ifconfig up of an LP PHY rev>=2 device on a debug kernel -> guaranteed panic. One-token polarity fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3834 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.7 KB | β raw | |
| VERDICT.md | β | 2.2 KB | β raw | |
| verdict.json | β | 2.7 KB | view raw | |
| fix.diff | β | 397 B | view raw | |
| env.txt | β | 1.1 KB | view raw | |
| manifest.json | β | 637 B | view raw |
DF-3834 β Inverted KASSERT in bwn_phy_lp_tblinit_r2 (rev < 2 must be rev >= 2) β guaranteed panic at PHY init on INVARIANTS kernels
- File:
sys/dev/netif/bwn/bwn/if_bwn_phy_lp.c(pass 2) - Class: CWE-617/CWE-588 unreachable-assert inversion β kernel panic at attach/init
- Severity: Low (INVARIANTS-only:
KASSERTcompiles to nothing on stock GENERIC, sys/sys/systm.h:117; bwn is compiled into X86_64_GENERIC, sys/config/X86_64_GENERIC:268) - Hardware-gated: fires for every LP PHY rev β₯ 2 device (b2063 radios, e.g. BCM4313/43225-class)
- Upstream-inherited: FreeBSD head
sys/dev/bwn/if_bwn_phy_lp.ccarries the same inverted assertion in itsbwn_phy_lp_tblinit_r2.
Build / Run / Expected
Hardware-gated (env.txt: no Broadcom wireless on the audit guest). On an INVARIANTS kernel with an LP PHY rev β₯ 2 card, simply bringing the interface up panics:
kldload bwn.ko / boot with the card # attach ifconfig bwn0 up # bwn_init -> bwn_chipinit -> mac_phy.init
Expected: panic: assertion "mac->mac_phy.rev < 2" failed in bwn_phy_lp_tblinit_r2 at ...:2742.
Root cause
bwn_phy_lp_tblinit dispatches on revision β if_bwn_phy_lp.c:1262-1270:
if (mac->mac_phy.rev < 2) {
bwn_phy_lp_tblinit_r01(mac); /* its KASSERT(rev < 2) is correct:2527 */
...
return;
}
bwn_phy_lp_tblinit_r2(mac); /* reached ONLY when rev >= 2 */
but bwn_phy_lp_tblinit_r2 opens with β if_bwn_phy_lp.c:2742:
KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
which contradicts its only call condition. The companion writers get it right
(bwn_phy_lp_gaintbl_write_r2: KASSERT(rev >= 2), line 3661). The assertion is inverted.
VERDICT β DF-3834
status: inconclusive (source-certain, hardware-gated) β reproduced: 0 β guest impact: none.
Proof chain
bwn_phy_lp_initβbwn_phy_lp_bbinit(if_bwn_phy_lp.c:440, 643-652) βbwn_phy_lp_tblinit(647) β forrev >= 2callsbwn_phy_lp_tblinit_r2(1269).bwn_phy_lp_tblinit_r2line 2742:KASSERT(mac->mac_phy.rev < 2, ...)β for every caller,rev >= 2holds, so on any kernel with INVARIANTS the assert fails unconditionally the first time an LP revβ₯2 PHY is initialized (device attach/ifconfig up, and again frombwn_phy_lp_bugfix:1174).KASSERTis only active with INVARIANTS (sys/sys/systm.h:94-96; no-op at 117). DragonFly's stock X86_64_GENERIC does not build with INVARIANTS, so production kernels never execute the assert β hence Low severity, but any debug/invariants kernel with the (GENERIC-included, sys/config/X86_64_GENERIC:268) bwn driver panics deterministically at first PHY init on this hardware class.- Upstream comparison: FreeBSD head sys/dev/bwn/if_bwn_phy_lp.c
bwn_phy_lp_tblinit_r2contains the identicalKASSERT(mac->mac_phy.rev < 2, ...)(verified against raw.githubusercontent.com/freebsd/freebsd-src/main, function starting at their line 2624) β the inversion is inherited from FreeBSD, and FreeBSD's ownbwn_phy_lp_gaintbl_write_r2(their line 3730) shows the intended polarityrev >= 2, matching DragonFly's correct usage at if_bwn_phy_lp.c:3661.
Guest
bwn is compiled into the guest kernel (kldstat -v: 62 siba_bwn/bwn) but there is no
Broadcom PCI device (env.txt) β bwn_attach never runs, the path cannot be exercised.
Guest kernel is stock GENERIC (no INVARIANTS) so even with hardware the assert would be inert
there; the panic requires an INVARIANTS build.
Fix
One-token fix: < 2 β >= 2 (fix.diff; git apply --check passes).
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_testableBaseline panic and patched non-panic both require an LP rev>=2 radio on an INVARIANTS kernel; no Broadcom hardware on the audit guest (env.txt). fix.diff is git-apply-able (verified).
fix.diff
Confirmed kernel references
Detail
Exploit chain
none beyond panic: attach an LP PHY rev>=2 card to an INVARIANTS kernel -> ifconfig bwn0 up -> deterministic panic (availability only, requires the hardware + debug kernel).
Evidence (decisive lines)
README.md/VERDICT.md (dispatch at 1262-1270 vs assert at 2742; companion asserts 2527/3661; upstream comparison); env.txt; fix.diff (one-token polarity fix, git-apply --check passes)
PoC changes
No PoC β needs LP PHY rev>=2 hardware; also note stock GENERIC masks the assert.
Verified recommended fix
Invert the assertion to KASSERT(mac->mac_phy.rev >= 2, ...) at if_bwn_phy_lp.c:2742 (fix.diff).
Verdict
bwn_phy_lp_tblinit_r2 (sys/dev/netif/bwn/bwn/if_bwn_phy_lp.c:2555) opens with KASSERT(mac->mac_phy.rev < 2, ...) at line 2742, but its sole caller (bwn_phy_lp_tblinit, line 1269) invokes it only when rev >= 2 β the assertion is inverted and fails unconditionally on the first LP-PHY-rev>=2 (b2063 radio) initialization. Because KASSERT is INVARIANTS-only (sys/sys/systm.h:94-118) stock GENERIC kernels are unaffected, but any INVARIANTS kernel panics deterministically at bwn attach/ifconfig up (bwn is compiled into X86_64_GENERIC, sys/config/X86_64_GENERIC:268). The polarity is proven wrong by the driver's own companions: tblinit_r01 asserts rev < 2 (line 2527, correct for its caller at 1263) and gaintbl_write_r2 asserts rev >= 2 (line 3661). Upstream FreeBSD head carries the identical inversion (verified in its bwn_phy_lp_tblinit_r2) β inherited, not DF-introduced. Not exercisable on the audit guest: bwn is in the kernel but no Broadcom PCI device exists (env.txt), so the PHY init path never runs.
No comments yet.