⬢ DragonFlyBSD Kernel Audit
DF-4713 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4713",
  "status": "untested",
  "reproduced": 0,
  "impact": "none demonstrated (hardware-gated: guest has no AMD GPU, amdgpu never binds); realistic ceiling is a hardirq NULL function-pointer call => kernel panic (local DoS) if an IH vector ever reaches a .process-less registered source (dce_virtual crtc_irq, LEGACY/229, num_types=7) or if a num_types>0 .set-less source is ever registered and the GPU-reset resume helper runs",
  "confidence": "likely",
  "verdict": "untested (runtime): amdgpu_irq_dispatch (amdgpu_irq.c:436) calls src->funcs->process and amdgpu_irq_update (amdgpu_irq.c:467) calls src->funcs->set without the NULL guards the file itself uses at :134 (disable_all), :520-521/:550-551 (get/put); amdgpu_irq_add_id (:359-360) only requires funcs != NULL, so .process-less/.set-less sources register fine. In-tree providers exist: dce_virtual_crtc_irq_funcs {.set=..., .process=NULL} (dce_virtual.c:757-760) registered with num_types=7 at LEGACY/229 (dce_virtual.c:375) - a stray/stale SMU_DISP_TIMER2 IV on a virtual-display config is a hardirq NULL-call panic; sdma illegal_inst sources have no .set but num_types==0 today, leaving amdgpu_irq_gpu_reset_resume_helper (:488-494 -> amdgpu_device.c:3287/3341) one registration away from a reset-path panic. Distinct from DF-4643 (that defect is the sleeping .set callback under the DragonFly sleepable-lockmgr shim - lock type verified here: spinlock_t == struct lock, spin_lock_irqsave == local_irq_save(crit_enter only) + lockmgr(LK_EXCLUSIVE), lockinit LK_CANRECURSE at amdgpu_irq.c:237). Fix compile-validated: full amdgpu KLD module build with -Werror, MOD_BUILD_RC=0, patched amdgpu_irq.c compiled at build.log:119.",
  "exploit_chain": [],
  "evidence": "findings/poc/DF-4713/VERDICT.md (callback-contract matrix, DF-4643 lock verification, all killed candidates incl. fini double-free and teardown ordering); build.log (full amdgpu module build, MOD_BUILD_RC=0 at :354, patched amdgpu_irq.c -Werror at :119); env.txt (no AMD GPU: pciconf shows only virtio-gpu 1af4:1234); fix.diff (2 NULL guards)",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:359",
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:436",
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:467",
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:134",
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:488",
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:520",
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:550",
    "sys/dev/drm/amd/amdgpu/amdgpu_irq.c:237",
    "sys/dev/drm/amd/amdgpu/dce_virtual.c:375",
    "sys/dev/drm/amd/amdgpu/dce_virtual.c:757",
    "sys/dev/drm/amd/amdgpu/sdma_v4_0.c:1748",
    "sys/dev/drm/amd/amdgpu/amdgpu_device.c:3287",
    "sys/dev/drm/include/linux/spinlock.h:75",
    "sys/dev/drm/include/linux/irqflags.h:34"
  ],
  "poc_changes": "n/a (no runtime PoC attempted; no AMD GPU on guest per DF-4519/DF-2201 hardware-gated protocol)",
  "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": 2400,
  "guest_dirty": 1,
  "build_cmd": "cd /usr/src && patch -p1 < /tmp/df4713_fix.diff && cd /usr/src/sys/dev/drm/amd/amdgpu && make obj && make",
  "run_cmd": "n/a (no AMD GPU on guest; amdgpu never probes)",
  "code_hash": null,
  "notes": "Verified across all 61 amdgpu_irq_add_id call sites: every num_types>0 source defines .set (illegal_inst sources lack .set but carry num_types==0), so the .set hole is not reachable with the current registry; the .process hole has exactly one in-tree NULL provider (dce_virtual crtc_irq). Negative results: fini double-registration safe (all double-registered srcs are static, data==NULL, enabled_types kfree(NULL) on 2nd pass); dispatch-vs-fini UAF closed by drm_irq_uninstall->free_irq->bus_teardown_intr synchronization before the kfree loop; add_id bounds/dup checks correct; get/put converge via amdgpu_irq_enabled re-read under lock; virk empty-then dead code.",
  "recommended_fix": "NULL-guard the two optional-callback calls: skip with DRM_DEBUG when funcs->process is NULL in amdgpu_irq_dispatch; return -EINVAL (after unlocking) when funcs->set is NULL in amdgpu_irq_update - matching the guards already used by amdgpu_irq_disable_all/amdgpu_irq_get/amdgpu_irq_put.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "build-only validation (runtime hardware-gated): fix.diff applied to guest /usr/src; full amdgpu KLD module build (make -C /usr/src/sys/dev/drm/amd/amdgpu) completed MOD_BUILD_RC=0 with -Werror; patched amdgpu_irq.c compiled at build.log:119 and amdgpu.ko linked. Baseline/patched runtime not observable without an AMD GPU.",
  "fix_evidence": "findings/poc/DF-4713/build.log (full untrimmed module build; decisive lines: 119 patched amdgpu_irq.c -Werror compile, 354 MOD_BUILD_RC=0)"
}