DF-5660 / verdict.json
{ "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" } |