⬢ DragonFlyBSD Kernel Audit
DF-4568 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4568",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Static verdict, defect proven at source level: guc_disable_communication() (intel_uc.c:226-237) calls intel_guc_ct_disable() at :231 \u2014 which frees and unmaps the shared CT page via ctch_close (intel_guc_ct.c:898) -> ctch_fini -> i915_vma_unpin_and_release(I915_VMA_RELEASE_MAP) (intel_guc_ct.c:214-218) \u2014 BEFORE gen9_disable_guc_interrupts() at intel_uc.c:233 masks+synchronize_irq()s the GuC events (i915_irq.c:555-567), and before guc->handler stops pointing at intel_guc_to_host_event_handler_ct (only switched at intel_guc_ct.c:902, after the free). A GuC event asserted in that window dispatches the CT handler into ct_process_host_channel (intel_guc_ct.c:815-840) which reads and writes through the freed descriptor (desc->head write at :628, is_in_error write at :838) \u2014 interrupt-context UAF read+write. The ctch_is_open() guard (:822) is an unlocked check-then-use on ctch->vma and cannot close the window. Unreachable on this tree: no platform ever sets info.has_guc_ct (intel_device_info.h:94 declared; i915_pci.c:469/:520 set only .has_guc), and enable_guc defaults to 0 (i915_params.h:49), so intel_guc_ct_disable can never run here; callers are privileged driver-lifecycle paths anyway. Filed as Info hardening; no runtime PoC possible (guest GPU is QEMU bochs std-VGA, no i915 device, and the window is not attacker-timed).",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-4568/VERDICT.md (ordering diagram with path:line); decisive lines: intel_uc.c:231 vs :233 (free-before-quiesce), intel_guc_ct.c:898 vs :902 (free-before-handler-swap), intel_guc_ct.c:214-218 (release map), intel_guc_ct.c:628/:838 (writes through desc), i915_irq.c:555-567 (disable+synchronize). fix.diff (2 files) applies clean via git apply --check.",
  "kernel_refs": [
    "sys/dev/drm/i915/intel_uc.c:226",
    "sys/dev/drm/i915/intel_uc.c:231",
    "sys/dev/drm/i915/intel_uc.c:233",
    "sys/dev/drm/i915/intel_guc_ct.c:887",
    "sys/dev/drm/i915/intel_guc_ct.c:898",
    "sys/dev/drm/i915/intel_guc_ct.c:902",
    "sys/dev/drm/i915/intel_guc_ct.c:214",
    "sys/dev/drm/i915/intel_guc_ct.c:815",
    "sys/dev/drm/i915/intel_guc_ct.c:628",
    "sys/dev/drm/i915/intel_guc_ct.c:838",
    "sys/dev/drm/i915/i915_irq.c:555"
  ],
  "poc_changes": "none \u2014 no PoC source exists; teardown race on a path unreachable on this tree (no platform sets has_guc_ct; enable_guc default 0) and not attacker-timed even where reachable.",
  "attempts": 0,
  "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": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "notes": "Info-tier lifetime hardening; upstream i915 later quiesced interrupts and switched the handler before freeing CT buffers. Guest has no Intel GPU; guest stays untouched (guest_dirty=0).",
  "recommended_fix": "In guc_disable_communication() call gen9_disable_guc_interrupts() and switch guc->send/guc->handler to nop BEFORE intel_guc_ct_disable(); inside intel_guc_ct_disable() swap send/handler before ctch_close() (see fix.diff).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "not_testable: the racing path is unreachable on this tree (no has_guc_ct platform, enable_guc default 0) and the guest has no Intel GPU, so neither baseline nor patched behavior can be exercised; the diff is line-accurate and git apply --check passes against the read-only sys/ tree.",
  "fix_evidence": "findings/poc/DF-4568/fix.diff (git apply --check clean); VERDICT.md section fix.diff."
}