{
  "finding_id": "DF-5571",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "DF-5561 twin confirmed on the vkernel64 copy of kdb_trap(): the db_global_jmpbuf re-entry path re-executes db_active++ (db_interface.c:169) while the abandoned outer invocations db_active-- (:177) never runs, permanently leaking db_active >= 1; user_trap()/kern_trap() (trap.c:366/605) then route every subsequent trap, including ordinary user-mode traps, into trap_fatal()+kdb_trap(), wedging the entire vkernel in ddb. Reproduced deterministically in a live vkernel booted on the QEMU guest: counter read 1 at the first prompt, `call 0x10()` faulted, counter read 2 at the re-entered prompt, `c` leaked it to 1, and the next user-mode trap (type 7, PID 1 sh) was taken to trap_fatal + all-CPU stop + ddb + nested-fault cascade; the shell never ran again (input eaten by ddb) and even the EOF panic re-entered Debugger(). With the one-line guard (if (db_active == 0) db_active++), the same sequence on a rebuilt vkernel keeps the counter at 1, /bin/fault gets normal SIGSEGV delivery, the shell answers POSTCONT-ALIVE, and shutdown is clean \u2014 fix validated.",
  "exploit_chain": "ddb session in the vkernel (SIGQUIT -> exc_debugger -> Debugger(), or sysctl debug.enter_debugger=ddb as root inside the vkernel, or panic with debugger_on_panic) -> ddb command faults outside db_nofault (`call 0x10()`, db_fncall has no fault guard) -> nested kdb_trap default case longjmps to db_global_jmpbuf -> setjmp returns, db_active++ runs a second time -> `c` exits only the re-entered session (single db_active--) -> db_active stuck at 1 -> trap.c:366/605 divert every subsequent trap to trap_fatal/kdb_trap -> all-CPU stop_cpus on each trap, nested faults cascade inside ddb -> permanent db> wedge of the whole vkernel process (no dump, no reboot, no access; even panic re-enters ddb).",
  "evidence": "run.baseline.log (== run.log) lines 50-69: x/x 0x11150a8 -> 1, call 0x10() -> Fatal trap 12 ... ip=0x2b:0x10 -> kernel: type 12 trap, code=0 -> re-entered db> -> x/x -> 2; lines 70-105: post-`c` Fatal trap 7 ... user mode ... current process = 1 (sh) -> kernel: type 7 trap -> CPU0 stopping CPUs -> nested Fatal trap 12 cascade -> echo POSTCONT-ALIVE -> No such command -> EOF panic re-entering ddb. run.fixed.log (== fix_run.log): counter 1 -> 1 across the re-entry, /bin/fault ... exited on signal 11 / Segmentation fault, POSTCONT-ALIVE printed, clean SIGTERM shutdown; Fatal trap count 5 (baseline) vs 1 (fixed).",
  "kernel_refs": [
    "sys/platform/vkernel64/x86_64/db_interface.c:150",
    "sys/platform/vkernel64/x86_64/db_interface.c:151",
    "sys/platform/vkernel64/x86_64/db_interface.c:167",
    "sys/platform/vkernel64/x86_64/db_interface.c:169",
    "sys/platform/vkernel64/x86_64/db_interface.c:177",
    "sys/platform/vkernel64/x86_64/trap.c:366",
    "sys/platform/vkernel64/x86_64/trap.c:605",
    "sys/platform/vkernel64/x86_64/trap.c:959",
    "sys/platform/vkernel64/x86_64/exception.c:277",
    "sys/platform/vkernel64/platform/console.c:404"
  ],
  "poc_changes": "Trigger is a vkernel ddb console sequence (SIGQUIT entry via the re-forked CHILD pid; vkernel ddb has no symbol table so the counter is read by literal address with `x/x 0x11150a8` from nm, not `print *db_active`), driven through a fifo console (vconsgetc is a blocking pread(0); the write end must be held open or EOF panics). Rig built: minimal UFS root image (vkinit /sbin/init opening /dev/console then execing sh \u2014 kernel-execd init_path=/bin/sh dies instantly; /bin/fault for the post-continue differential), pristine image rebuilt each phase (vkernel boot wipes the MBR), DF-5474 link fix required to build VKERNEL64 at all.",
  "attempts": 3,
  "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 (guest); vkernel: DragonFly 6.5-DEVELOPMENT #0: Wed Oct  7 21:18:08 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/VKERNEL64",
  "runtime_sec": 2400,
  "guest_dirty": 0,
  "build_cmd": "cd /usr/src && patch -N -p1 < /tmp/linkfix-df5474.diff && patch -N -p1 < /tmp/df5571_fix.diff && make -j6 nativekernel KERNCONF=VKERNEL64",
  "run_cmd": "sh mk_image.sh && sh vk_ddb_session.sh /usr/obj/usr/src/sys/VKERNEL64/kernel.debug baseline 0x11150a8   # then ... fixed 0x11150a8 with the patched kernel",
  "code_hash": "b99a6d3691296ce2b414820d7f9dbfb8edd94cbc0ee8d790bde00e72a1032a4c",
  "notes": "Pass-2 re-audit of sys/platform/vkernel64/x86_64/db_interface.c; DF-5561 lead verified as an exact twin (identical setjmp/increment/longjmp shape and identical trap.c routing). Adjacent observations NOT filed (different file): vkernel64 lacks pc64s panicstr guard around the stopped_cpus mask check (db_interface.c:185-192); vconsgetc panics on console EOF (console.c:416); trap.c gd_trap_nesting_level balances its own ++/-- so the longjmp does not leak it here; db_read_bytes/db_write_bytes (:231-307) match pc64s coherent nofault-guard shape. Impact ceiling is a permanent all-CPU ddb wedge of the vkernel (single host process hosting all guest processes); no memory corruption, no uid-0 route.",
  "recommended_fix": "Guard the re-entry increment: `if (db_active == 0) db_active++;` after the setjmp in kdb_trap() (mirrors the validated DF-5561 pc64 fix).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Applied fix.diff (guard) in the guest scratch tree, rebuilt the vkernel (nativekernel RC=0, db_interface.o recompiled), re-ran the identical trigger sequence: counter 1 -> 1 across the nested re-entry (baseline 1 -> 2), no post-continue trap storm, /bin/fault delivered as a normal user SIGSEGV, shell alive (POSTCONT-ALIVE printed), clean shutdown. Leak signature eliminated.",
  "fix_evidence": "fix_run.log (= run.fixed.log): 0x11150a8: 1 at both prompts, pid 2 (fault), uid 0: exited on signal 11, POSTCONT-ALIVE, Caught SIGTERM ... Shutting down...; fix_build.log (= build.log): build completed RC=0; run.baseline.log for the contrast (counter 2, trap storm, wedge)."
}