mpr_pci_free destroys the parent DMA tag while mpr_free can early-return without freeing the 7 child tags β DragonFly's bus_dma_tag_destroy kfree()s unconditionally, permanently leaking all IOC-facts DMA memory and tags on a wedged-controller failed attach
Summary
mpr_free early-returns skip iocfacts_free while the PCI layer unconditionally destroys the parent tag; DFly's tag destroy has no child-ref check, so the parent is freed under 7 live children holding a dangling pointer - permanent DMA-memory+tag leak per failed attach. Hw-gated. Route-through-iocfacts_free fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4955 Β· 1 files| File | Type | Description | Size | |
|---|---|---|---|---|
| verdict.json | file | 1.2 KB | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Exploit chain
wedged IOC -> transition failures -> mpr_free early return skips iocfacts_free -> parent tag destroyed under live children -> children+DMA leak permanently
Evidence (decisive lines)
findings/poc/DF-4955/ (this verdict; code-trace proof)
Verdict
Hardware-gated (wedged LSI SAS3 card at attach): mpr_free can early-return (subsystem-detach or transition_ready failure on the same dead card) WITHOUT running mpr_iocfacts_free, while mpr_pci_free unconditionally destroys the parent DMA tag - DFly bus_dma_tag_destroy has no child-reference check (kfree unconditionally, unlike FreeBSD's refcounted EBUSY), so the parent is freed and the 7 child tags + all their IOC-facts DMA memory leak forever holding a dangling parent. ~hundreds of KB per failed attach, amplifiable via devctl retry. Permanent leak only (callouts drained first - no UAF). Route-early-returns-through-iocfacts_free fix (or harden bus_dma_tagDestroy).
No comments yet.