⬢ DragonFlyBSD Kernel Audit
DF-5660 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5660",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "shutdown.c:97s reboot(RB_POWEROFF) binds to the HOST libc reboot(2) (no kernel symbol `reboot` exists; the vkernel links as an ordinary host program -- nm: U reboot@DF404.0) and demonstrably executes from shutdown_intrs initproc==NULL branch: three independent vkernel cores show frame #1 at shutdown.c:97 calling into ld.so/libcs reboot path (one died at the lazy-PLT resolver, one inside libc reboot->umtx_wakeup). The branch requires a SIGTERM processed in the microsecond SYSINIT sliver between initshutdown (SI_BOOT2_PROC0) and create_init (SI_SUB_CREATE_INIT); ordinary kill timing cannot land there (ithread latency >> sliver) but a same-uid kill-storm does -- all three cores were produced that way. End-to-end completion of the host reboot was prevented in the lab only by the storm triggers own userspace re-entrancy damage (SIGILL inside ld.so/libc mid-call), not by any kernel-side check: the vkernel runs as root and nothing downstream rejects reboot(2). With the fix (fix.diff, 3 hunks) the reboot() call is structurally gone: the storm trigger never trips the interposed reboot, the guest host never cycles, and every shutdown_intr execution takes the in-kernel path (shutdown_nice -> boot() -> cpu_halt -> exit(EX_OK), full transcript in DF-5661/run.fixboot.log).",
  "exploit_chain": "same-uid local process (operator script / monitoring / host shutdown) -> SIGTERM storm against the booting root-owned vkernel -> one hit processed between register_int_virtual(2) and fork1s initproc assignment -> shutdown_intr else-branch -> host libc reboot(2) request -> host kernel reboot/poweroff attempt (full machine availability loss; on the audit guest this cycles the VM)",
  "evidence": "nm_reboot_proof.txt (UND reboot@DF404.0 vs kernel sys_reboot/shutdown_nice); core_backtraces.txt (3x gdb: frame at shutdown.c:97 -> ld.so resolver / libc umtx_wakeup); sigill_deaths.txt (host log of the three crashing runs); bootlog_excerpt.txt (serial console); VERDICT.md narrative",
  "kernel_refs": [
    "sys/platform/vkernel64/platform/shutdown.c:97",
    "sys/platform/vkernel64/platform/shutdown.c:61",
    "sys/platform/vkernel64/conf/Makefile:23",
    "sys/kern/kern_shutdown.c:158",
    "sys/kern/kern_shutdown.c:182",
    "sys/sys/kernel.h:178",
    "sys/sys/kernel.h:183"
  ],
  "poc_changes": "Interposer evolved through v1-v7: v1 single kill inside the sigaction() wrapper was silently dropped (sched_ithd_intern drops ISTATE_NOTHREAD interrupts, kern_intr.c:585) because register_int_virtual(2) runs after the sigaction; v2/v3 fork-storm reached the branch (cores) but storm re-entrancy killed the process inside ld.so/libc; v4/v5 pthread-sniper bursts always executed shutdown_intr post-create_init (latency); final rig = fork-storm + reboot() interposer tripwire (logs howto, silences storm, masks signals, issues syscall(55) = the same syscall libcs wrapper issues) + LD_BIND_NOW. Guest-side sed capped the storm loop at 4M kills in the last build (hash of the local shutrig.c is authoritative).",
  "attempts": 9,
  "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": 2820,
  "guest_dirty": 1,
  "build_cmd": "cc -shared -O2 -fPIC -o /root/shutrig.so /root/shutrig.c   (rig: make -j6 nativekernel KERNCONF=VKERNEL64 with DF-5474 defsym workaround; sh build_image.sh)",
  "run_cmd": "sh /root/run5660.sh trigger   (env LD_BIND_NOW=1 LD_PRELOAD=/root/shutrig.so ./kernel.debug -m 512m -r /vkroot.img -n 2 -e init_path=/bin/vkinit -s)",
  "code_hash": "ee1167953d11e81e502e660e12f016cfb74b55cf10ef32fd7a0528c3effec929",
  "notes": "Siblings: DF-5661 (same functions ksignal no-op). The kern_closefrom curproc==NULL assertion (kern_descrip.c:1420) discovered during fix validation is fixed by the third hunk of fix.diff. Storm-collateral SIGILL deaths of the vkernel itself are the DF-5587/5607 signal-context fragility class (not re-reported here).",
  "recommended_fix": "Gate ksignal(initproc, SIGUSR2) on SIGISMEMBER(initproc->p_sigacts->ps_sigcatch, SIGUSR2) and make the fallback shutdown_nice(RB_POWEROFF|RB_HALT); never call bare reboot() from vkernel kernel context (binds to host libc reboot(2)).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "Baseline: storm trigger drove shutdown.c:97 into the host libc reboot path (three cores at the callsite). Patched (fix.diff applied to guest /usr/src, VKERNEL64 rebuilt): identical storm trigger produced NO reboot() call (interposer tripwire silent), the guest host never rebooted, and every shutdown_intr execution took the in-kernel halt path instead.",
  "fix_evidence": "fix.diff; run fix transcript in ../DF-5661/run.fixboot.log (boot() called on cpu#0 -> The operating system has halted. -> cpu halt, exiting vkernel); bootlog_excerpt.txt"
}