{
  "finding_id": "DF-2777",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Reproduced on the stock INVARIANTS guest with dormant stall hooks compiled into kern_intr.c at the exact window boundaries the finding cites (after info->i_state = ISTATE_NORMAL at kern_intr.c:326 before the i_thread allocation/creation, and at the emergency_intr_thread NULL check at :308). SC1: a second concurrent register_int(254, INTR_MPSAFE|INTR_CLOCK, cpu2) observed ISTATE_NORMAL with a NULL i_thread and faulted writing TDF_CLKTHREAD at kern_intr.c:349 (Stopped at register_int+0x1b9 lock orl 0x20000000,0xd8 rdx; VA 0xd8 = offsetof td_flags). SC2: with the first registrant stalled mid-window and the second rec linked, sched_ithd_soft(255) faulted reading info->i_thread->td_gd at kern_intr.c:589 (Stopped at sched_ithd_intern+0x1f movq 0xb8 rdx; VA 0xb8). SC3: two concurrent first-registrations on cpu2 (rig reopened the boot-time emergency window via dfh_reset_emergency, since a booted system has already created each cpu emergency thread) both ran systimer_init_periodic_nq on emergency_intr_timer[2]; the second re-init of an armed timer crashed inside systimer_add (Stopped at systimer_add+0x15c, VA 0, thread CRIT; the kern_systimer.c:148 SYSTF_ONQUEUE assert is bypassed because re-init wipes flags). Threat model: all triggers are kernel-internal (driver probe/attach races, boot-time first-registration concurrency, interrupt arrival during first registration); unprivileged users cannot drive register_int, so the ceiling is a kernel panic (DoS) at attach/boot time; severity Low as filed. Fix validated on a rebuilt kernel with the same orchestration: SC1 and SC3 print non-NULL results and survive, SC2 degrades to a rate-limited stray-interrupt report, no panics.",
  "exploit_chain": "",
  "evidence": [
    "panic_sc1.txt: Stopped at register_int+0x1b9 lock orl 0x20000000,0xd8 rdx -- TDF_CLKTHREAD store through NULL i_thread",
    "panic_sc2.txt: DF2777-SC2 calling sched_ithd_soft(255) ... Stopped at sched_ithd_intern+0x1f movq 0xb8 rdx -- td_gd read through NULL i_thread",
    "panic_sc3.txt: Stopped at systimer_add+0x15c movq rcx rsi (VA 0, CRIT) -- double concurrent systimer_init_periodic_nq",
    "df2777_fixed.dmesg: SC1/SC2/SC3 survived on the fixed kernel (stray report for SC2)",
    "run.log: full stock and fixed A/B transcript",
    "src/kern_intr.hooks_stock.diffside.c and src/kern_intr.pristine.c: exact hook placement vs stock"
  ],
  "kernel_refs": [
    "sys/kern/kern_intr.c:308",
    "sys/kern/kern_intr.c:326",
    "sys/kern/kern_intr.c:327",
    "sys/kern/kern_intr.c:349",
    "sys/kern/kern_intr.c:589",
    "sys/kern/kern_systimer.c:148"
  ],
  "poc_changes": "Runtime kldload GPFs on this guest, so the interposition is compiled into kern_intr.c as two dormant hook calls (df2777_hook) placed exactly at the window boundaries, plus a rig-only dfh_reset_emergency helper for SC3 (boot-time window reopen, labeled as rig). The stall hooks are no-ops unless armed via sysctl dfh.",
  "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",
  "runtime_sec": 2400,
  "guest_dirty": 0,
  "build_cmd": "cd /usr/src && make -j6 nativekernel KERNCONF=X86_64_GENERIC (stock+hooks build build.log.gz; fixed+hooks build build.fixed.log.gz)",
  "run_cmd": "sysctl dfh.scen2777=1 dfh.run2777=1 ; sysctl dfh.scen2777=2 dfh.run2777=1 ; sysctl dfh.scen2777=3 dfh.run2777=1",
  "code_hash": "9d114ea5b0e9cd57db016d471fbab552ae4dad52d85367e6aab84237b8c0fefc",
  "notes": "SC3 needs the rig reopen because a booted system already created every cpu emergency thread (first boot registration wins); the underlying code defect is the ungated check-then-create. The kern_systimer.c:148 INVARIANTS assert does not prevent the crash because re-initialization wipes the flags first. Guest reset with-src after evidence collection.",
  "recommended_fix": "Gate ithread creation with atomic_cmpset into a new ISTATE_CREATING state and publish i_thread before i_state; NULL-guard the INTR_CLOCK flag store and treat NULL i_thread in sched_ithd_intern as a stray; gate the emergency-thread block with a once-only cmpset (see fix.diff)."
}
