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

Unbounded ccb_index from firmware LRAM into ccb_infos[] heap OOB read + attacker-influenced pointer deref

Summary

adv_run_doneq looks up completed CCB by indexing adv->ccb_infos[scsiq.d2.ccb_index] where ccb_index is u_int32_t read straight from firmware LRAM. No bounds check against max_openings (ccb_infos array size). Corrupted/maliciously-crafted ccb_index reads OOB struct adv_ccb_info from kernel heap and immediately dereferences its ->ccb pointer and writes to it turning OOB read into kernel panic or with heap grooming memory-corruption primitive. Driver originally writes cinfo-adv->ccb_infos into that LRAM field when submitting but trusts value blindly on read-back. Same unbounded pattern recurs in advlib.c:1988 (adv_abort_ccb). cur_active decrement also unguarded #ifdef DIAGNOSTIC only. [VERIFIED pass2: reproduced - in-bounds-unallocated ccb groomed pointer drives Fatal trap 12 write at poison+offsetof csio resid; same defect as DF-4349 re-verified on shipped kernel]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2413 Β· 10 files
FileTypeDescriptionSize
README.md β€” 294 B ↓ raw
VERDICT.md β€” 1.6 KB ↓ raw
build.sh β€” 67 B view raw
dfadv24.c β€” 46.2 KB view raw
env.txt β€” 254 B view raw
fix.diff β€” 628 B view raw
manifest.json β€” 708 B view raw
panic.txt β€” 559 B view raw
run.sh β€” 120 B view raw
verdict.json β€” 2.1 KB view raw

DF-2413 -- evidence pack

Verdict: reproduced (reproduced=1, impact=panic, confidence=certain)

Build: see build.sh Run: sh primeadv.sh; sysctl kern.df43xx.go=3

See VERDICT.md for the full narrative, run.log/panic.txt for the decisive output, fix.diff for the post-verification fix.

VERDICT.md
↓ download raw

DF-2413 VERDICT

Status: reproduced Impact: panic Confidence: certain

Same defect family as DF-4349 (this finding is its narrow re-statement at advansys.c:1106-1108): unvalidated ccb_index from firmware LRAM indexes ccb_infos[] and the ->ccb pointer is immediately dereferenced for a write. Re-verified this session on the shipped kernel with the DF-4349 facetB rig: done entry naming ccb_index=10 (in bounds, never allocated, heap-groomed ccb=0x41df41df41df) -> Fatal trap 12, fault VA = 0x41df41df42f3 (poison + offsetof(csio.resid)), stopped at adv_intr+0x101 movl %edi,0x114(%rsi) - the ccb->csio.resid store through the OOB-read pointer. A wild u_int32 index (0x41414141) variant did not fault on this guest (landing zone readable); the in-bounds-unallocated variant above is the demonstrated write primitive.

Kernel references

Guest

DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

Notes

near-duplicate of DF-4349 (verified earlier); the additional claim (u_int32 wild index) did not fault here but needs the same bounds check

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_testable
↓ fix.diffper-fix-DF-2413

Confirmed kernel references

Detail

Exploit chain

firmware LRAM ccb_index -> ccb_infos[idx].ccb (OOB read) -> ccb->csio.resid write at attacker-groomed address -> kernel memory write primitive -> panic or corruption

Evidence (decisive lines)

panic.txt (fault VA = groom + offsetof(csio.resid), stopped at the resid store)

PoC changes

existing DF-4349 rig re-run; no changes

Verified recommended fix

bounds+state check before deref: if (ccb_index >= adv->max_openings || cinfo->state != ACCB_ACTIVE) drop the completion (the DF-4349 fix covers this)

Verdict

Same defect family as DF-4349 (this finding is its narrow re-statement at advansys.c:1106-1108): unvalidated ccb_index from firmware LRAM indexes ccb_infos[] and the ->ccb pointer is immediately dereferenced for a write. Re-verified this session on the shipped kernel with the DF-4349 facetB rig: done entry naming ccb_index=10 (in bounds, never allocated, heap-groomed ccb=0x41df41df41df) -> Fatal trap 12, fault VA = 0x41df41df42f3 (poison + offsetof(csio.resid)), stopped at adv_intr+0x101 movl %edi,0x114(%rsi) - the ccb->csio.resid store through the OOB-read pointer. A wild u_int32 index (0x41414141) variant did not fault on this guest (landing zone readable); the in-bounds-unallocated variant above is the demonstrated write primitive.