DF-2946 / verdict.json
{ "finding_id": "DF-2946", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "init_param1() (sys/kern/subr_param.c:202) overwrites stathz with the raw kern.stathz boot tunable with no validation; the value reaches initclocks_other() (kern_clock.c:438-441) which registers the statclock systimer with SYSTF_MSSYNC, and _systimer_init_periodic() (kern_systimer.c:270-273) / cputimer_default_fromhz() (kern_cputimer.c:199) divide by it unguarded. A single planted line kern.stathz=\"0\" in /boot/loader.conf boots past init_param1 and kills the kernel at SI_BOOT2_POST_SMP with 'Fatal trap 18: integer divide fault ... idivq' (panic.txt), leaving the machine dead in DDB โ unbootable until the tunable is removed. Negative or huge stathz similarly produce a negative/garbage statclock period or an interrupt storm. Same loader.conf trust boundary as DF-0173 (kern.hz=0), but a different tunable and a different, later sink: DF-0173 divides inside init_param1 (subr_param.c:204-207); kern.stathz=0 passes those divides (hz itself stays valid) and detonates in the systimer subsystem. The tree even guards stathz==0 elsewhere (kern_clock.c:1337 'stathz ? stathz : hz'), confirming the systimer path is the omission.", "exploit_chain": "1) privileged/console plant: kern.stathz=\"0\" in /boot/loader.conf; 2) init_param1 ingests it unvalidated into stathz; 3) boot proceeds (hz valid, in-file divides fine); 4) initclocks_other at SI_BOOT2_POST_SMP calls systimer_init_periodic_flags(..., stathz=0, SYSTF_MSSYNC); 5) 1000/freq (or fromhz) executes idivq by zero -> Fatal trap 18 -> DDB; machine will not boot until loader.conf is repaired. Ceiling: persistent boot DoS (no post-boot or unprivileged trigger exists โ kern.stathz has no runtime sysctl).", "evidence": [ "panic.txt โ 'Fatal trap 18: integer divide fault while in kernel mode' / 'kernel: type 18 trap' / 'Stopped at -0x7f9a53d9: idivq %r12,%eax' / 'db>' immediately after 'Initialize MI interrupts for 6 cpus'", "env.txt โ stock kernel identity (6.5-DEVELOPMENT #0, X86_64_GENERIC, hw.ncpu=6) and clean baseline vfs.nbuf/maxfiles/maxproc before the plant", "run.sh โ exact host-side reproduction sequence (plant -> reboot -> down at 75s -> reset)", "VERDICT.md โ analysis, duplicate-separation vs DF-0173/2915-17, and the refuted negative-kern.nbuf hypothesis (unsigned-promotion rescue in cpu_startup caps)", "fix.diff โ hz/stathz validation in init_param1 + freq<=0 guard in _systimer_init_periodic" ], "kernel_refs": [ "sys/kern/subr_param.c:202", "sys/kern/subr_param.c:200-207", "sys/kern/kern_clock.c:438-441", "sys/kern/kern_systimer.c:270-273", "sys/kern/kern_cputimer.c:197-200", "sys/kern/kern_clock.c:1337" ], "poc_changes": "no compilation needed: the trigger is a single loader.conf line (plant.sh); predicted sink (1000/freq under SYSTF_MSSYNC vs fromhz) confirmed only by trap signature + boot position since the INVARIANTS kernel exports no symbols to the serial console", "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": 190, "guest_dirty": 0, "build_cmd": "n/a (boot-tunable trigger; no build step)", "run_cmd": "vm.sh run_root 'printf \"kern.stathz=\\\"0\\\"\\n\" >> /boot/loader.conf && sync'; vm.sh run_root 'shutdown -r now'; sleep 75; vm.sh status; grep 'Fatal trap 18' dfbsd-qemu/boot.log; vm.sh reset with-src", "code_hash": "c89a1b9df4f5d7d7b204889595b35e386fa4dee07d4a9875f900776e94ca9363", "notes": "Guest returned to clean with-src snapshot (vm.sh status = up) after verification. Related family notes: kern.hz>1e6 makes ustick==0 (post-boot unprivileged div-by-zero at kern_time.c:511 etc.) and kern.hz<0 poisons MSSYNC periods โ both share DF-0173's fix locus (hz validation), so the fix.diff clamps both ends of hz and floors stathz. kern.nbuf=-1048576 was empirically REFUTED as a boot breaker (caps promote to unsigned and clamp it sane; boot.log shows 'Warning: nbufs capped at 67098975 due to kvm' then '129940 due to physmem').", "recommended_fix": "Validate clock tunables in init_param1: clamp hz to [1,1000000] (default on violation) and floor stathz at 1 (default hz+1); defense-in-depth freq<=0 guard in _systimer_init_periodic.", "fix_status": "not_testable", "fix_kernel_uname": "", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Fix not built in-guest: Low-severity boot-DoS class with no demonstrated memory corruption (per contract, guest fix-validation cycles are reserved for memory-corruption findings); fix.diff is a minimal, line-accurate clamp authored against the read-only sys/ tree.", "fix_evidence": ["fix.diff"] } |