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

MFI_DCMD_LD_DELETE post-check assumes the volume still exists: AEN-driven deletion during the DCMD round-trip hits KASSERT('volume dissappeared')/NULL->ld_dev deref

Summary

mfi_check_command_post re-walks mfi_ld_tqh after the LD_DELETE DCMD completes and KASSERTs ld!=NULL then dereferences ld->ld_dev; the pre-check's existence guarantee is voided if the AEN task deletes the volume mid-roundtrip (decode_evt performs device_delete_child without mfi_config_lock). Release builds NULL-deref -> panic. The developer's own commented-out twin fix ('Fix: for kernel panics when SSCD is removed') proves this race class has panicked in the field. Replace-KASSERT-with-break fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3877 Β· 6 files
FileTypeDescriptionSize
README.md β€” 1.4 KB ↓ raw
VERDICT.md β€” 1.0 KB ↓ raw
fix.diff β€” 520 B view raw
manifest.json β€” 651 B view raw
verdict.json β€” 1.2 KB view raw
env.txt β€” 283 B view raw

DF-3877 β€” MFI_DCMD_LD_DELETE pre/post-check race with AEN-driven volume deletion (KASSERT/NULL deref)

mfi_check_command_post (mfi.c:2624-2637) re-walks mfi_ld_tqh after the DCMD completes:

TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
    if (ld->ld_id == cm->cm_frame->dcmd.mbox[0])
        break;
}
KASSERT(ld != NULL, ("volume dissappeared"));
if (cmd_status == MFI_STAT_OK) {
    ... device_delete_child(sc->mfi_dev, ld->ld_dev);   /* ld NULL deref */

The pre-check (mfi.c:2570-2579) verified the volume exists and disabled the disk, but between pre and post the AEN task can remove it: mfi_handle_evt -> mfi_decode_evt MR_EVT_ARGS_LD_STATE OFFLINE (mfi.c:1494-1511) performs device_delete_child WITHOUT holding mfi_config_lock (the io-protected detach at mfi_disk.c:189-191 blocks on io_lock, which the post-check holds β€” the deletion lands between the DCMD round-trip windows). When the volume is gone, ld == NULL: - INVARIANTS kernels: KASSERT panic ("volume dissappeared" β€” the developer's own comment at mfi.c:1503-1505 shows this exact class already panicked once and was papered over in mfi_decode_evt); - release kernels: ld->ld_dev / mfi_disk_enable(ld) NULL deref -> panic.

Operator-group trigger: race an LD_DELETE management ioctl against a volume going offline (or two paths that delete concurrently). Low: needs device access + event timing.

VERDICT.md
↓ download raw

DF-3877 VERDICT β€” inconclusive (hardware-gated), speculative race

  • Pre/post asymmetry verified (mfi.c:2570-2579 vs 2624-2637); the KASSERT text and the commented-out twin in mfi_decode_evt (mfi.c:1502-1505, "Fix: for kernel panics when SSCD is removed") evidence the race family is real.
  • AEN deletion path takes no config lock (mfi.c:1494-1511) while the ioctl path serializes LD_DELETEs through mfi_config_lock (mfi.c:2530-2543) β€” cross-path serialization is missing.
  • Requires an mfi adapter, operator access, and a volume-state transition racing the ioctl: cannot be exercised on the guest; speculative timing.
  • fix.diff NULL-guards the post-walk result like the decode_evt twin.

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

guard fix; not validatable without HW

fix.diff
↓ fix.diffper-fix-DF-3877

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md

PoC changes

no runnable PoC (race + HW)

Verified recommended fix

NULL-guard ld in mfi_check_command_post like the decode_evt twin

Verdict

LD_DELETE pre-check validates the volume, post-check assumes it still exists and KASSERTs/derefs NULL when an AEN offline event removes it mid-DCMD; the driver's own commented-out twin fix (mfi.c:1502-1505) proves the pattern has panicked before. Race + operator access needed; guarded fix attached.