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

dpt_get_conf ready-wait is an unbounded, interrupts-disabled spin driven only by HBA register values β€” hostile status shape hangs the kernel at attach

Summary

Inside crit_enter() the ready-wait loop has no iteration bound: it exits only on three exact status-byte values plus not-busy, or on 'DPT' at regs 0..2. A controller parking its status register elsewhere, or staying busy forever, hard-spins the kernel on MMIO reads at probe - boot-time hang, no break-out. Bound-the-loop fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4245 Β· 6 files
FileTypeDescriptionSize
README.md β€” 776 B ↓ raw
VERDICT.md β€” 1.2 KB ↓ raw
env.txt β€” 1.0 KB view raw
fix.diff β€” 1.1 KB view raw
verdict.json β€” 1.7 KB view raw
manifest.json β€” 592 B view raw

DF-4245 β€” dpt_get_conf() ready-wait spins forever (with interrupts disabled) on a hostile HBA status shape

Inside crit_enter() (interrupts disabled), dpt_get_conf() waits for the controller to become ready (dpt_scsi.c:505-520). The loop has NO iteration bound and NO timeout: it exits only on (a) one of three exact status-byte values AND controller-not-busy, or (b) registers 0..2 spelling 'DPT' (dpt_raid_busy). dpt_wait() itself gives up after ~1s but its failure merely keeps the outer loop spinning. A controller that parks its status register on any other value (or stays busy forever) hangs the kernel in a hard MMIO-read spin at probe/attach β€” no timer, no watchdog break-out at that point in boot. Same hostile-input-shape family as DF-4042/4098, hang flavor.

VERDICT.md
↓ download raw

DF-4245 verdict β€” UNTESTED (hardware-gated); missing loop bound certain from source

Reproduced?

No β€” requires a DPT controller reporting a stuck status byte; guest has no DPT hardware (env.txt).

Certainty

dpt_scsi.c:505-520: the while condition is (status not in 3 exact values) || (dpt_wait(HA_SBUSY,0) != 0). dpt_wait is bounded (20000*50us, dpt_scsi.c:198-212) but only its RESULT feeds the outer loop, which has no iteration cap and no DELAY; the sole early-exits are the 3 good statuses, or 'DPT' at regs 0..2 (dpt_raid_busy, dpt_scsi.c:171-180). All inputs device-fed; loop runs under crit_enter() (dpt_scsi.c:498). Consequence: boot-time or devd-time hard hang from a faulty/hostile card; availability only. Severity Low (hardware-gated, probe-time).

Fix validation

Not possible without hardware; fix.diff bounds the loop (~60s of dpt_wait passes) and returns failure like the existing RSUS path.

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
baseline no→ patch + rebuild →patched clean

fix.diff authored against the read-only sys/ tree; kernel-level fix validation impossible without DPT SmartRAID hardware (none in guest, no QEMU emulation exists).

fix.diff
↓ fix.diffper-fix-DF-4245

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md; dpt_scsi.c:498,505-520; dpt_wait 198-212; dpt_raid_busy 171-180

PoC changes

No seed PoC existed; evidence authored from scratch in this run.

Verified recommended fix

Bound the ready-wait loop and fail attach cleanly (fix.diff).

Verdict

Untested on guest (hardware-gated). Source-certain: the ready-wait loop at dpt_scsi.c:505-520 has no iteration bound; every exit condition except spinning forever depends on device-fed register values; it runs with interrupts disabled (crit_enter at 498). Hostile status shape = hard hang at probe.