{
  "finding_id": "DF-4546",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "lm_detach() (lm78.c:445-458) unconditionally calls sensordev_deinstall() on a ksensordev that was never installed: wb_match() claims the W83791SD without a sensor table (lm78.c:590-592, the only chip case with no lm_setup_sensors), so numsensors==0 makes lm_attach() return early (lm78.c:427-429) before sensordev_install(). sensordev_deinstall (kern_sensors.c:153-176) runs TAILQ_REMOVE (sys/sys/queue.h:646-662) on the zeroed never-inserted node: head->tqh_last = NULL (global sensordev_list corrupted) followed by *(tqe_prev==NULL) = tqe_next -- an immediate NULL-pointer WRITE, i.e. a kernel panic on any later driver detach (kldunload/devctl) of the bound lm(4) device. Reproduced with a macro-faithful lifted-copy harness (verbatim TAILQ_REMOVE from queue.h, struct ksensordev per sensors.h:156-166, zeroed softc): BUG case faults writing to 0x0 inside the deinstall; CONTROL (numsensors=19) and PATCHED (fix.diff guard) detach cleanly. In-kernel path hardware-gated (no LM78-class chip on the guest); trigger is privileged detach on rare hardware -> Low severity, root-triggered DoS.",
  "exploit_chain": "",
  "evidence": "run.log (BUG case: >>> SIGSEGV: kernel-equivalent NULL-pointer WRITE at 0x0 inside sensordev_deinstall; CONTROL + PATCHED clean); run.2.log (repeat); fix_build.log (kernel-toolchain -fsyntax-only of patched lm78.c: PATCHED_RC=0, deliberate-error negative control NEGCTL_RC=1); fix.diff (git apply --check OK)",
  "kernel_refs": [
    "sys/dev/powermng/lm/lm78.c:590",
    "sys/dev/powermng/lm/lm78.c:427",
    "sys/dev/powermng/lm/lm78.c:450",
    "sys/kern/kern_sensors.c:153",
    "sys/kern/kern_sensors.c:160",
    "sys/sys/queue.h:646",
    "sys/sys/sensors.h:156",
    "sys/dev/powermng/lm/lm78var.h:126"
  ],
  "poc_changes": "authored fresh this run (pass 2); no seed PoC existed",
  "attempts": 2,
  "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": 180,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh  (cc -O2 -Wall -o lm_detach_nullwrite lm_detach_nullwrite.c on the guest)",
  "run_cmd": "sh run.sh  (./lm_detach_nullwrite)",
  "code_hash": "2efe60dd3d3e7e77e4d78e9061d741869c72f6fd87686a3d9562507cada2ddef",
  "notes": "macro-level lifted-copy harness: the sensor task framework itself is NOT racy here (sensor_task_thread runs st->func holding thr->lock, kern_sensors.c:307-341, so sensor_task_unregister blocks and no post-unregister refresh can run -- negative-checked this pass). Same zero-sensor shape would fire for any future match entry added without a sensor table.",
  "recommended_fix": "guard lm_detach with if (sc->numsensors == 0) return 0; (fix.diff) -- nothing was installed, so nothing may be deinstalled",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Patched kernel not runnable against real W83791SD hardware on the guest (no LM78-class chip). fix.diff is git-apply-able, compiles clean under the kernel toolchain in the X86_64_GENERIC objdir (-fsyntax-only, RC=0, with a deliberate-error negative control failing RC=1), and the harness PATCHED control detaches the zero-sensor device without a fault.",
  "fix_evidence": "fix.diff; fix_build.log (PATCHED_RC=0, NEGCTL_RC=1); run.log PATCHED case (clean detach)",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 x86_64 (kernel objdir syntax validation)"
}