sf_attach() bus_setup_intr() failure path double-invokes ether_ifdetach() and passes a NULL intr cookie to bus_teardown_intr()
Summary
On bus_setup_intr failure after ether_ifattach succeeded, the attach calls ether_ifdetach itself and then jumps to fail: which invokes sf_detach - device_is_attached is still true, so the full teardown runs a second time: ether_ifdetach again (non-idempotent: duplicate TAILQ_REMOVE/list corruption/panic) and bus_teardown_intr with the never-set NULL cookie. IRQ exhaustion at kldload/boot. Remove-premature-detach + NULL-guard fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4328 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.1 KB | β raw | |
| VERDICT.md | β | 1.7 KB | β raw | |
| fix.diff | β | 953 B | view raw | |
| verdict.json | β | 1.6 KB | view raw |
DF-4328 β sf_attach() bus_setup_intr() failure path: double ether_ifdetach()
and bus_teardown_intr(NULL cookie)
File: sys/dev/netif/sf/if_sf.c:773-787 (attach error path), sys/dev/netif/sf/if_sf.c:791-820 (sf_detach)
If bus_setup_intr() fails after ether_ifattach() succeeded, sf_attach()
calls ether_ifdetach(ifp) itself and then jumps to fail: which invokes
sf_detach(dev). device_is_attached() is still true there, so sf_detach()
runs the full teardown a SECOND time: ether_ifdetach() again (double
if_detach(): duplicate TAILQ_REMOVE from ifnetlist, duplicate
ifnet_array_del, double devctl/route announcements, double
mcl_inclimit decrement β list corruption/panic) and
bus_teardown_intr(dev, sc->sf_irq, NULL) with the unset cookie.
Trigger: IRQ resource exhaustion / MSI setup failure at kldload or boot β privileged/admin-initiated. Severity Low.
Not run on the guest (requires forcing bus_setup_intr failure on a driver whose hardware is absent); source-level finding only. fix.diff removes the premature ether_ifdetach() and guards the teardown cookie.
DF-4328 β verdict: NOT REPRODUCED ON GUEST (source-level; hardware/driver-gated)
Root cause (path:line)
- sys/dev/netif/sf/if_sf.c:777-780 β on bus_setup_intr() failure:
ether_ifdetach(ifp); device_printf(...); goto fail; - sys/dev/netif/sf/if_sf.c:786 β
fail: sf_detach(dev); - sys/dev/netif/sf/if_sf.c:796 β device_is_attached(dev) is still true (device detach flags unchanged), so sf_detach executes:
- :802
ether_ifdetach(ifp)β SECOND time. ether_ifdetach -> if_detach (sys/net/if.c:949+) is not idempotent: second run re-announces IFAN_DEPARTURE/devctl, re-runs TAILQ_REMOVE(&ifnetlist,...), ifnet_array_del() on an array no longer containing ifp, double mcl_inclimit decrement, double ifgroup teardown -> list corruption or panic. - :799
bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand)with sc->sf_intrhand == NULL (setup failed).
Why not reproduced
Requires an sf(4) device whose interrupt setup fails at attach (IRQ exhaustion); the guest has no AIC-6915 hardware, so neither the success nor the failure path of sf_attach can execute. Reported at source-level certainty (Low severity, root/admin trigger: kldload/boot-time only).
Fix
fix.diff: drop the duplicate ether_ifdetach() from the attach error path (sf_detach already performs it) and NULL-guard the teardown cookie.
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_testableno hardware path on guest to validate
fix.diff authored
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md path:line analysis (if_sf.c:777-787, 796-820; sys/net/if.c:949+)
PoC changes
none (no PoC run)
Verified recommended fix
remove premature ether_ifdetach() in the attach error path; NULL-guard bus_teardown_intr cookie
Verdict
Source-level finding, not exercisable on the audit guest: sf_attach()'s bus_setup_intr() failure path double-ether_ifdetach'es the ifnet (sf_detach runs the teardown again because device_is_attached() is still true) and passes a NULL intr cookie to bus_teardown_intr. Non-idempotent if_detach corrupts ifnet lists / double-decrements cluster limits. Requires IRQ-setup failure at kldload/boot on sf(4) hardware (privileged trigger) - Low.
No comments yet.