{
  "finding_id": "DF-4684",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Deterministically reproduced on the guest that amdgpu_fence_wait_emptys upstream safety bail is dead code on this port: the reader (amdgpu_fence.c:306-307, replicated verbatim in a KLD against the ports own dma_fence/call_rcu/kmem_cache primitives) loads the array slot, the fence-completion IRQ ordering (amdgpu_fence_process :252-264) releases the fence to zero and queues call_rcu, and the readers dma_fence_get_rcu then takes a reference on the already-released fence \u2014 the ports dma_fence_get_rcu (dma-fence.h:97-103) is an unconditional kref_get under rcu_read_lock()==preempt_disable (rcupdate.h:46-56), so the !get_rcu bail at :307 can never fire. The hypothesized double-free tail (resurrect->put->second call_rcu on the same rcu_head->kmem_cache_free twice) is EMPIRICALLY BLOCKED on this port: the ports refcount_inc saturates a zero count to REFCOUNT_SATURATED 0xC0000000 (refcount.h:53-60), the readers put lands at 0xBFFFFFFF, releases=1 frees=1, post-run allocs distinct (run.log). The freed-and-reused-memory variant is unreachable because the readers window is preempt_disabled (interrupts only, milliseconds) while the delay line cannot free for >=1s \u2014 unlike DF-4510s synchronously-kfreed syncobj stubs. Net: a genuine contract violation (use of a logically-dead fence + dead bail path) with no memory corruption on current port semantics; containment is incidental to refcount_inc saturation, so the one-line header fix is warranted as hardening. In-situ IRQ race not exercisable on this guest (no AMD GPU; QEMU virtio-gpu only); the deterministic KLD replay runs the identical code path.",
  "exploit_chain": "",
  "evidence": "run.log (baseline: refcount resurrected to 3221225472, RESULT: releases=1 frees=1 ... SATURATION ... BLOCKED); run.fixed.log (patched header: dma_fence_get_rcu(...) = 0 -> get_rcu refused the dead fence ... no put); VERDICT.md line-accurate race + why-saturation-saves analysis; df4684.c the verbatim replica",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/amdgpu_fence.c:295-316",
    "sys/dev/drm/amd/amdgpu/amdgpu_fence.c:244-265",
    "sys/dev/drm/amd/amdgpu/amdgpu_fence.c:631-649",
    "sys/dev/drm/amd/amdgpu/amdgpu_pm.c:2133-2146",
    "sys/dev/drm/include/linux/dma-fence.h:97-103",
    "sys/dev/drm/include/linux/rcupdate.h:46-56",
    "sys/dev/drm/include/linux/refcount.h:39",
    "sys/dev/drm/include/linux/refcount.h:53-60",
    "sys/dev/drm/linux_rcu.c:56-78"
  ],
  "poc_changes": "authored fresh KLD (df4684.c): replicates emit/process/wait_empty/release/free verbatim with the ports primitives; two revisions \u2014 first proved the double-free tail, then re-instrumented (release/free counters) after discovering refcount_inc saturation blocks it; MODULE_DEPEND(drm) deliberately omitted because DFs linker does not refcount module deps (kern_linker.c:574), which made kldunload tear down drm.ko and wedge in a wait_event",
  "attempts": 4,
  "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 (baseline); fixed-kernel A/B on rebuilt nativekernel #0: Tue Sep 22 20:34:56 UTC 2026",
  "runtime_sec": 2100,
  "guest_dirty": 1,
  "build_cmd": "cd /root/poc/DF-4684 && make -m /usr/share/mk KMODDIR=$PWD",
  "run_cmd": "kldload drm && kldload ./df4684.ko && sysctl kern.df4684_run=1; sleep 6; dmesg | tail -15",
  "code_hash": "8644e7cfcde0e6f7e78a631b4bff42a0f3de90aaa545db7ffc59c4f98b96a47f",
  "notes": "This is the amdgpu instance of the DF-4510-family lockless-fence-get pattern the pass-2 brief asked to check: it exists but in weakened, saturation-contained form (no memory corruption today). Known DF-1807 not re-reported. Killed in pass 2: concurrent amdgpu_fence_process walkers are serialized into disjoint walk ranges by the last_seq cmpxchg; emits slot-overwrite does not leak the old array ref (process NULLs+puts before emits overwrite can observe it); wait_polling timeout arithmetic sound; debugfs cpu_addr+2/4/6 reads stay inside the wb aperture. Fix validated A/B incl. full nativekernel rebuild RC=0 under -Werror with both this and DF-4685s fix applied (build_kernel.log); /usr/src restored pristine afterwards (md5-verified); guest reset with-src before return.",
  "recommended_fix": "dma_fence_get_rcu(): kref_get_unless_zero + return NULL on a dead fence (dma-fence.h:97-103) \u2014 same shape as the DF-4510 header fix; linux_reservation.c:357 already expects this contract",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "A/B on the guest: baseline (stock headers) resurrects the dead fence (run.log); with fix.diff applied to the guest /usr/src copy and the module rebuilt against it \u2014 first on the stock drm.ko, then on a fully rebuilt kernel (make -j6 nativekernel KERNCONF=X86_64_GENERIC RC=0 under -Werror, installed and rebooted) \u2014 dma_fence_get_rcu returns 0, the reader takes the upstream bail (get_rcu refused the dead fence -> wait_empty returns 0, no put), and exactly one legitimate free fires (run.fixed.log). No regression: linux_reservation.c consumers already check the get_rcu return value.",
  "fix_evidence": "run.log vs run.fixed.log; fix.diff (git-apply clean against sys/); build_kernel.log (nativekernel RC=0, 35574-line build log); post-validation md5 restore of /usr/src/sys/dev/drm/include/linux/dma-fence.h = 190f4a4ad15ce6247620a63e98c75327 (pristine)"
}