DF-2946 / plant.sh
#!/bin/sh # DF-2946 trigger — plant an unvalidated clock tunable. # # sys/kern/subr_param.c:202 fetches kern.stathz with TUNABLE_INT_FETCH and # performs NO validation (no >= 1 check, no upper bound). The value flows # untouched into initclocks_other() (kern_clock.c:438-441) which registers # the statclock systimer with SYSTF_MSSYNC, and _systimer_init_periodic() # computes its period as: # # if ((flags & SYSTF_MSSYNC) && freq <= 1000) # info->periodic = sys_cputimer->fromhz(1000) * (1000 / freq); <-- 1000/0 # else # info->periodic = sys_cputimer->fromhz(freq); <-- freq/freq # # (sys/kern/kern_systimer.c:270-273, sys/kern/kern_cputimer.c:197-200) # # kern.stathz=0 -> integer divide fault at boot (Fatal trap 18). # kern.stathz<0 -> negative period, garbage statclock expiry. # kern.stathz huge -> sub-nanosecond statclock period (interrupt storm). # # Trust boundary: /boot/loader.conf (loader prompt / root edit) — the same # boundary as DF-0173 (kern.hz=0) and DF-2894 (kenv ingest). This finding # is the *stathz* member of the family: DF-0173 only covers the in-file # division at subr_param.c:204-207 (hz==0); kern.stathz=0 boots *past* # init_param1 and detonates later in SI_BOOT2_POST_SMP. # # SETUP (in guest, as root): cp /boot/loader.conf /boot/loader.conf.df2946bak printf 'kern.stathz="0"\n' >> /boot/loader.conf sync # RUN (in guest, as root): # shutdown -r now # # EXPECTED: kernel dies during boot, serial console shows # Fatal trap 18: integer divide fault while in kernel mode # ... # CPU0 stopping CPUs: ... # Stopped at ...: idivq %r12,%eax # db> # right after "Initialize MI interrupts for 6 cpus" (initclocks_other). |