⬢ DragonFlyBSD Kernel Audit
DF-4466 / verdict.json
← back to finding ↓ download raw
{
 "finding_id": "DF-4466",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "panic",
 "confidence": "certain",
 "verdict": "Deterministic use-after-free (3/3 kernel panics, Fatal trap 12 supervisor write to 0x0 in mpipe_alloc_callback+0x1a2) plus permanent in-flight-bio hangs: dm-crypt completions run asynchronously holding only bio_caller_info1.ptr while suspend(no-op)/reload/resume destroys the table config with no drain. Root-triggerable via the routine LVM reload flow on busy volumes; freed config is zero-wiped (NULL write) or attacker-reclaimable (priv->ivgen->gen_iv indirect call) - memory-corruption class.",
 "exploit_chain": "priv UAF: (1) crypt->delay(12s) stack parks a read bio; (2) suspend+reload-with-fast-table+resume frees old config immediately (dm_table_destroy, no drain); (3) completion derefs freed config: zero-wiped chunk gives NULL-page write (observed panic); reclaimed chunk gives mpipe_alloc_callback on controlled mpipe then priv->ivgen->gen_iv indirect call and forged crypto session -> kernel code execution on the no-SMAP/SMEP/KASLR guest. Full uid=0 chain not completed (trigger itself requires /dev/mapper/control = root); no structural blocker documented in VERDICT.md.",
 "evidence": "run.log + panic.txt: Fatal trap 12, Stopped at mpipe_alloc_callback+0x1a2 (3/3 from fresh resets); ps_hang_variantD.txt: writers in D forever; fix_run.log: patched kernel drains (resume blocks 11s) and read returns correct 0x9e111cd8, no panic; VERDICT.md timeline.",
 "kernel_refs": [
  "sys/dev/disk/dm/crypt/dm_target_crypt.c:693",
  "sys/dev/disk/dm/crypt/dm_target_crypt.c:750",
  "sys/dev/disk/dm/crypt/dm_target_crypt.c:607",
  "sys/dev/disk/dm/crypt/dm_target_crypt.c:976",
  "sys/dev/disk/dm/device-mapper.c:408",
  "sys/dev/disk/dm/device-mapper.c:550",
  "sys/dev/disk/dm/dm_ioctl.c:440",
  "sys/dev/disk/dm/dm_ioctl.c:508",
  "sys/dev/disk/dm/dm_table.c:129"
 ],
 "poc_changes": "Replaced the seeded sketch with a proplib-XML ioctl client (plistref ABI requires <plist> wrapper, hex integers); added warm-up read (open-time label probe eats one delay round); variant F reloads a FAST table to bypass the accidental disk_config() probe-drain that shields naive reload reproducers; 6 variants (A-F) developed to characterize which destroy paths race.",
 "attempts": 9,
 "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
 "runtime_sec": 2380,
 "guest_dirty": 0,
 "build_cmd": "cc -O2 -o dmrace dmrace.c -lpthread",
 "run_cmd": "sh run.sh (variant F0)",
 "code_hash": "5ac343aac65dccb8bfa98ca7760b4fb69471b278c00fa01f2fe0cfbebfde1858",
 "notes": "INVARIANTS kernel. QEMU CPU has no AESNI (software crypto). Variant B (hammer+equal-table reload) is shielded by dmsetdiskinfo disk_config probe-wait only when the reloaded table is equally slow; with a fast reloaded table (normal lvextend case) the destroy proceeds while bios are in flight. is_open is a plain flag (device-mapper.c:212/232) - related core defect enabling remove-path exposure.",
 "recommended_fix": "Per-bio in-flight reference on the crypt config (nactive) incremented in strategy under the table lock and dropped at every completion endpoint; destroy drains nactive before mpipe/session teardown.",
 "fix_status": "fixed",
 "fix_baseline_reproduced": 1,
 "fix_patched_reproduced": 0,
 "fix_kernel_uname": "DragonFly 6.5-DEVELOPMENT #1: Sun Sep 20 13:35:38 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
 "fix_verdict": "fix.diff applied in-guest, nativekernel+installkernel, rebooted: exact F0 PoC no longer panics - resume now blocks ~11s draining the in-flight read (tsleep dmtcdn), read returns correct plaintext 0x9e111cd8 errno=0, config freed afterwards; variant B (36k writes, 10 reload cycles) clean; guest stable.",
 "fix_evidence": "fix_run.log (patched timeline: resume 13.0s->24.1s, reader correct), fix_build.log (full build, DONE=0), /boot/kernel/dm_target_crypt.ko contains dmtcdn ident."
}