DragonFlyBSD Kernel Audit
DF-2828 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2828",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "ckpt_thaw_proc() calls vmspace_exec(p, NULL) (kern_checkpoint.c:556) without first making the process single-threaded. pmap_replacevm() asserts p->p_nthreads == 1 (pmap.c:6378) and only re-points the first LWP; vmspace_exec() then drops the old vmspace reference. A 2-thread process calling sys_checkpoint(CKPT_THAW,...) on any parseable image panics deterministically on the stock INVARIANTS kernel: 'panic: assertion \"p->p_nthreads == 1\" failed in pmap_replacevm' with the trace pmap_replacevm<-vmspace_exec<-sys_sys_checkpoint<-sys_xsyscall<-syscall2. On non-INVARIANTS production kernels the KKASSERT is compiled out and the remaining LWPs keep lwp_vmspace pointing at the released vmspace (vmspace UAF) - analysis only, not executed. Gate: kern.ckptgroup (wheel by default).",
  "exploit_chain": "",
  "evidence": [
    "panic.txt: assertion failure with full kernel trace through sys_sys_checkpoint",
    "trigger_mt.c: 2-thread THAW trigger",
    "gen.c: image generator (any parseable image suffices; nfiles=0 used)"
  ],
  "kernel_refs": [
    "sys/kern/kern_checkpoint.c:556",
    "sys/vm/vm_map.c:4298-4331",
    "sys/platform/pc64/x86_64/pmap.c:6368-6387"
  ],
  "poc_changes": "Simple pthread trigger; reuses the DF-2826 generator.",
  "attempts": 1,
  "guest_uname": "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",
  "runtime_sec": 90,
  "guest_dirty": 1,
  "build_cmd": "cc -O -o trigger_mt trigger_mt.c -lpthread (plus gen/build from ../DF-2826)",
  "run_cmd": "./gen clean.ckpt stage2.bin normal 0x600000f0 0 && ./trigger_mt",
  "code_hash": "trigger_mt.c sha256 computed at filing; generator identical to ../DF-2826/gen.c",
  "notes": "The non-INVARIANTS vmspace-UAF consequence is traced, not run (no production-kernel build in this session). Fix is a policy decision (reject multi-threaded THAW vs stop other LWPs like ckpt_freeze_proc does) - left to upstream.",
  "recommended_fix": "Ensure single-threadedness before vmspace_exec() in the CKPT_THAW path: return EINVAL if p->p_nthreads > 1, or proc_stop(p, SCORE) + wait (mirroring ckpt_freeze_proc) and unstop after the restore.",
  "fix_status": "not_testable",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Not kernel-validated: the natural fix is a policy change (reject or serialize multi-threaded THAW) rather than a mechanical one-line correctness fix; recommend upstream decide. The baseline panic reproduction is captured in panic.txt.",
  "fix_evidence": "findings/poc/DF-2828/panic.txt; findings/poc/DF-2828/README.md (recommended fix)"
}