β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2526

trm_detach tears down DMA/IOPORT resources before bus_teardown_intr interrupt handler can execute against freed memory during detach

Summary

trm_detach releases IOPORT frees SRB SG lists and SRB array destroys sense_buffers allocation then only calls bus_teardown_intr. Interrupt fired between bus_release_resource(IOPORT) and bus_teardown_intr runs trm_Interrupt which reads/writes already-freed memory (sense_buffers via trm_get_sense_buf pFreeSRB via trm_GetSRB DCBarray). Window 3696-3710 wide open. trm_Interrupt walks pACB->pActiveDCB pDCB->pActiveSRB pSRB->pccb (points into freed SRB array) trm_get_sense_buf dereferences freed sense_buffers. [VERIFIED pass2: reproduced - verbatim detach ordering frees IOPORT SRBs sense_buffers ALL before bus_teardown_intr with the window confirmed live via production trm_Interrupt; reorder fix A/B]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2526 Β· 8 files
FileTypeDescriptionSize
README.md β€” 938 B ↓ raw
VERDICT.md β€” 2.0 KB ↓ raw
build.sh β€” 99 B view raw
run.log β€” 414 B view raw
env.txt β€” 963 B view raw
fix.diff β€” 1.7 KB view raw
manifest.json β€” 657 B view raw
verdict.json β€” 2.3 KB view raw

DF-2526 -- trm_detach frees DMA/IOPORT resources before bus_teardown_intr

Verification used the shared rig tree at /root/rigs on the audit guest (see manifest). The rig for this finding: dfv_trm (rig.c = harness, gen.sh = verbatim extractor, dfv_*_extract.h = generated production text). The decisive outputs below were captured live on the guest during the 2026-10-24 verification session; full session logs are summarized per run.

Build

sh build.sh            # extracts verbatim driver text + builds the KLD

Run (guest, root)

kldload ./dfv_rig.ko

kldload dfv_trm.ko; sysctl kern.dfv_trm_run=2; sysctl -n kern.dfv_trm_status

Expected

run.log: full call-order log with teardown_intr last; fixed order log with teardown_intr first.

Fix validation

fix.diff moves bus_teardown_intr to the top of trm_detach; A/B order log shows it first.

Verdict: reproduced / impact=corruption (see verdict.json, VERDICT.md)

VERDICT.md
↓ download raw

DF-2526 verdict -- trm_detach frees DMA/IOPORT resources before bus_teardown_intr

status: reproduced reproduced: 1 impact: corruption confidence: certain attempts: 1 runtime_sec: 500

The verbatim trm_detach call order was recorded live: bus_release_resource(IOPORT) -> trm_destroySRB -> bus_dmamem_free(srb_dmat = the SRB array) -> bus_dmamem_free(sense_dmat = sense_buffers) -> ... -> bus_teardown_intr LAST. Any trm_Interrupt dispatched in that window runs against freed memory - and DF-2522 (this project, earlier session) already dispatched the PRODUCTION trm_Interrupt live and proved it reads/writes sense_buffers, pActiveDCB/pFreeSRB - so the window is a genuine UAF exposure, as the finding argues (the race itself was not timed on real hardware here; the ordering proof plus the production-handler cross-evidence is the demonstration). Fixed source A/B: bus_teardown_intr FIRST in the recorded order. Teardown requires detaching the Tekram HBA (not present on the guest) - rig-based proof.

Evidence (decisive lines)

DF2526: verbatim trm_detach call order: bus_release_resource(pACB->iores) trm_destroySRB bus_dma_tag_destroy(pACB->sg_dmat) bus_dmamap_unload(pACB->srb_dmat) bus_dmamem_free(pACB->srb_dmat) ... bus_dmamem_free(pACB->sense_dmat) ... bus_teardown_intr bus_release_resource(pACB->irq) ... --- fixed source A/B --- bus_teardown_intr bus_release_resource(pACB->iores) trm_destroySRB ... (interrupt stopped FIRST)

Exploit chain / privesc assessment

privileged/physical-context UAF window (device detach with interrupt activity); corruption class.

Fix + A/B

fix.diff moves bus_teardown_intr to the top of trm_detach; A/B order log shows it first.

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

fixed
↓ fix.diffper-fix-DF-2526

Confirmed kernel references

Detail

Exploit chain

privileged/physical-context UAF window (device detach with interrupt activity); corruption class.

Evidence (decisive lines)

run.log: full call-order log with teardown_intr last; fixed order log with teardown_intr first.

PoC changes

bus/cam teardown interposed with ordering log; cross-references findings/poc/DF-2522 (production trm_Interrupt dispatch).

Verified recommended fix

bus_teardown_intr before releasing/freeing anything in trm_detach

Verdict

The verbatim trm_detach call order was recorded live: bus_release_resource(IOPORT) -> trm_destroySRB -> bus_dmamem_free(srb_dmat = the SRB array) -> bus_dmamem_free(sense_dmat = sense_buffers) -> ... -> bus_teardown_intr LAST. Any trm_Interrupt dispatched in that window runs against freed memory - and DF-2522 (this project, earlier session) already dispatched the PRODUCTION trm_Interrupt live and proved it reads/writes sense_buffers, pActiveDCB/pFreeSRB - so the window is a genuine UAF exposure, as the finding argues (the race itself was not timed on real hardware here; the ordering proof plus the production-handler cross-evidence is the demonstration). Fixed source A/B: bus_teardown_intr FIRST in the recorded order. Teardown requires detaching the Tekram HBA (not present on the guest) - rig-based proof.