exca_activate_resource leaks the ExCA window when parent BUS_ACTIVATE_RESOURCE fails (and exca_mem_map on its memreg error return) β permanent per-socket window-exhaustion DoS
Summary
The window bit is claimed via io_map/mem_map before the parent activation; if the parent fails, the error returns without releasing it, and deactivate never unwinds it (gated on RF_ACTIVE which a failed activation never sets). Each failed activation permanently burns one of 5 memory windows or one of only 2 I/O windows - afterwards every 16-bit PC Card on that socket fails to map resources until reboot. Hardware-gated per-socket availability attack (insert/remove churn with failing parent activations). Same defect on mem_map's early return. Release-on-error fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4572 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | β | 4.4 KB | β raw | |
| README.md | β | 902 B | β raw | |
| run.sh | β | 172 B | view raw | |
| run.log | β | 941 B | view raw | |
| env.txt | β | 682 B | view raw | |
| fix.diff | β | 1.3 KB | view raw | |
| manifest.json | β | 1.2 KB | view raw | |
| verdict.json | β | 2.8 KB | view raw |
DF-4572 evidence pack β exca window leak on activation failure
Status: INCONCLUSIVE (PoC not runnable: guest has no CardBus/PCMCIA hardware). The finding itself is a certain code-level defect; see VERDICT.md for the full path:line trace and the on-hardware trigger procedure.
Contents: VERDICT.md full narrative + reachability trace + trigger procedure run.sh guest-side hardware-presence check (what was executed) run.log output of run.sh on the audit guest (NO_CARDBUS_BRIDGE, ...) env.txt guest uname + device state fix.diff inspection-validated fix (releases the leaked window bits) manifest.json artifact catalog verdict.json machine verdict (status: inconclusive; persist_poc-compatible)
Reproduce the environment check: ./run.sh (on the audit guest or any DF box) Reproduce the finding: requires pccbb hardware β see VERDICT.md Β§Trigger.
DF-4572 β exca window allocation leaked on activation failure (per-socket DoS)
- File:
sys/dev/pccard/exca/exca.c(pass 2, GLM 5.3) - Class: resource leak on error path β availability DoS of a PC Card socket
- Severity: Low (hardware-gated: requires a pccbb CardBus bridge + 16-bit PC Card)
- Confidence: certain (code defect), likely (realistic trigger)
Summary
exca_activate_resource() (sys/dev/pccard/exca/exca.c:779) programs an ExCA
memory or I/O window (exca_mem_map / exca_io_map, which claim a window via
sc->memalloc/sc->ioalloc bits at exca.c:250-255 / 468-473) and only then
calls the parent bridge's BUS_ACTIVATE_RESOURCE (exca.c:800). If the parent
activation fails, the error is returned without releasing the window bit.
exca_deactivate_resource() (exca.c:804-822) only unmaps windows when the
resource carries RF_ACTIVE β a resource whose activation failed never has
it β so there is no unwind path at all. Each failed activation permanently
consumes one of the socket's 5 memory windows (EXCA_MEM_WINS,
excavar.h:72) or one of its 2 I/O windows (EXCA_IO_WINS, excareg.h:229).
After enough failures, exca_io_map/exca_mem_map always return 1 and every
subsequent 16-bit PC Card on that socket fails to attach.
Sibling instance of the same defect: exca_mem_map() grabs the window bit at
exca.c:252 and returns 1 at exca.c:260-262 ("Does not support mapping above
24M") without releasing it. On current DragonFly that branch is unreachable
(the only live caller path is pccbb PCI, which sets EXCA_HAS_MEMREG_WIN
unconditionally at sys/dev/pccard/pccbb/pccbb_pci.c:332), but it is the same
shared code and trivially fixed together.
Reachability (pass-2 trace)
- Only live consumers of exca.c on DragonFly are the pccbb PCI bridges:
exca_reset(pccbb.c:1232),exca_activate_resource/exca_deactivate_resource(pccbb.c:1286/1294),exca_mem_set_flags(pccbb.c:1390),exca_mem_set_offset(pccbb.c:1406),exca_insert/exca_removal. The ISA path (exca_probe_slots, pccbb_isa.c:161) is dead:cbb_isa_activate()returns ENOMEM unconditionally (pccbb_isa.c:134-138) socbb_isa_probe()bails before ever probing slots. exca_activate_resourceruns whenever a 16-bit PC Card function driver activates an I/O or memory resource on the socket β i.e. at card insertion / driver attach, driven by the cbb event thread and devd.- The parent call is
BUS_ACTIVATE_RESOURCE(parent=cbb)β rman/PCI mapping of the resource; failure modes include rman range exhaustion and failed pmap/bus-space activation under memory pressure.
Why "inconclusive" (not reproduced here)
The audit QEMU guest has no CardBus/PCMCIA hardware and none can be attached with the standard QEMU machine model (no i82365/pci-to-cardbus bridge emulation):
pciconf -lshows no class=0607 device (NO_CARDBUS_BRIDGE)devinfoshows no pccard/cbb/exca devices- VGA is QEMU virtio-gpu (0x1234:1111), no drm/i915 modules loaded
The trigger therefore cannot execute on this guest even as root. The defect
itself is unambiguous from the source: there is no code path that clears the
window bit between exca_io_map/exca_mem_map success and the failing
parent BUS_ACTIVATE_RESOURCE, and exca_deactivate_resource is gated on
RF_ACTIVE.
Trigger on real hardware (documented procedure)
- Machine with a pccbb-class PCI CardBus bridge (e.g. Ricoh RL5c476,
TI PCI1420) β
pciconf -lv | grep -B3 cardbus. - Force repeated failed parent activation for a 16-bit PC Card's resources
(e.g. exhaust the rman window the bridge maps into so
BUS_ACTIVATE_RESOURCEat exca.c:800 returns non-zero), then remove and re-insert the card (devd hotplug cycles). - After 2 failed I/O activations (or 5 failed memory activations) the socket is dead for 16-bit cards: every subsequent attach logs "exca_io_map: no windows available"-equivalent failure (exca_io_map returns 1 at exca.c:474-475) until reboot.
Fix
Release the window when the parent activation fails, and on exca_mem_map's
error return β see fix.diff (validated by inspection; cannot build-test a
pccbb kernel path on this guest).
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 validated by inspection only: fix.diff restores the window bit on both error paths (exca.c:258-262 and the parent-activate failure in exca_activate_resource) and cannot regress the success path; no pccbb hardware on the guest to build/run a single-fix kernel against.
fix.diff in findings/poc/DF-4572/
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md (path:line trace + on-hardware trigger); run.log/env.txt (guest hardware absence: NO_CARDBUS_BRIDGE); fix.diff (releases window bits on both error paths)
PoC changes
n/a β no PoC build possible; only the environment check run.sh was executed on the guest
Verified recommended fix
Release the ExCA window bit when parent BUS_ACTIVATE_RESOURCE fails, and on exca_mem_map's memreg error return (fix.diff)
Verdict
Code-level defect is certain: exca_activate_resource (exca.c:779-802) claims an ExCA window via exca_io_map/exca_mem_map and then calls the parent bridge's BUS_ACTIVATE_RESOURCE (exca.c:800) with no unwind on failure; exca_deactivate_resource (exca.c:808) is gated on RF_ACTIVE, which a failed activation never sets, so the window bit (5 MEM / 2 IO per socket) is leaked permanently and repeated failures exhaust the socket's windows (exca_io_map returns 1 at exca.c:474). Not runnable on the audit guest: QEMU exposes no CardBus/PCMCIA bridge (no PCI class 0607 device, devinfo has no pccard/cbb/exca, run.log), so impact could not be demonstrated at runtime. Impact ceiling: per-socket availability DoS of 16-bit PC Card resource mapping, hardware-gated (pccbb bridge + card insertion cycles), no kernel memory corruption.
No comments yet.