{
  "finding_id": "DF-4522",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "REAL BUG, proven two ways, runtime-gated on absent hardware. (1) Static proof (static_proof.sh, PASS): the only rb_leftmost references in all of sys/ are the two READ sites of the amdgpu_vm_fini cleanup loop (amdgpu_vm.c:3325-3326); the shims rb_insert_color_cached/rb_erase_cached (sys/dev/drm/include/linux/rbtree.h:100-103) never write the cache field and sys/tree.h has no leftmost concept, while vm->va is deterministically zero-initialized (amdgpu_vm.c:3055, LINUX_RB_ROOT_CACHED). Therefore the DragonFly fini loop executes ZERO iterations and its list_del/amdgpu_vm_it_remove/kfree body (amdgpu_vm.c:3331-3333) is dead code: every struct amdgpu_bo_va_mapping still in the tree at amdgpu_vm_fini leaks permanently (~80B M_DRM each, amdgpu_vm.c:2526/2580). The leads infinite-loop hypothesis is REFUTED (field is NULL-forever, never garbage); the leak hypothesis is CONFIRMED. Reachable via the deliberate reserve-failure leak path in amdgpu_gem_object_close (amdgpu_gem.c:170-175 leaves mappings for fini to reclaim) and any still active bo inside vm condition (amdgpu_vm.c:3313). (2) On-kernel semantic demo (run.log): a kld built against the real rbtree.h running the verbatim amdgpu shim + verbatim fini loop shows BUGGED fini loop: iterations=0 freed=0 LEAKED=64 with the tree still nonempty, while the fixed loop drains 64/64. Status is not_testable only because the guest has no AMD GPU (amdgpu.ko cannot attach); impact recorded none per the honest-status table for the runtime row, but the defects real-world effect is a repeatable kernel memory leak on AMD GPU systems, filed as Low severity / CWE-401.",
  "exploit_chain": "",
  "evidence": "static_proof.sh (5 assertions, PASS, host); run.log lines DF4522: BUGGED fini loop: iterations=0 freed=0 LEAKED=64 (tree still nonempty=1) and DF4522: FIXED fini loop: iterations=64 freed=64 LEAKED=0; df4522_demo.c (verbatim shim amdgpu_vm.c:100-127 + verbatim loop amdgpu_vm.c:3325-3334); build.log (kld build, -Werror clean); baseline_build.log + fix_build.log (amdgpu.ko RC=0 unmodified and with fix.diff); VERDICT.md full trace; env.txt (guest has no AMD GPU: kldstat kernel+ehci/xhci only)",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:3325",
    "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:3333",
    "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:3055",
    "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:107",
    "sys/dev/drm/amd/amdgpu/amdgpu_gem.c:170",
    "sys/dev/drm/amd/amdgpu/amdgpu_kms.c:1073",
    "sys/dev/drm/include/linux/rbtree.h:100",
    "sys/dev/drm/include/linux/rbtree.h:104",
    "sys/dev/drm/linux_compat.c:40"
  ],
  "poc_changes": "Lead arrived as a task_log note, no seed PoC. Built from scratch: (a) static_proof.sh grep-level proof over sys/; (b) df4522_demo.c kld -- includes the REAL sys/dev/drm/include/linux/rbtree.h and RB_GENERATEs linux_root like linux_compat.c:40 (drm.ko unloaded on guest, no symbol clash); carries the shim and fini loop VERBATIM from amdgpu_vm.c with three marked adaptations (reduced mapping struct, private MALLOC_DEFINE, list_del omitted); (c) guest build quirks solved: base64(1) absent -> openssl base64 transfer; -j8 module build races forwarder-header generation -> use -j1; single-object make target missing forwarder dir -> full make only.",
  "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",
  "runtime_sec": 940,
  "guest_dirty": 0,
  "build_cmd": "guest: cd /tmp/df4522demo && make SYSDIR=/usr/src/sys (demo kld); cd /usr/src/sys/dev/drm/amd/amdgpu && make -j1 (baseline + patched amdgpu.ko)",
  "run_cmd": "guest: kldload ./df4522demo.ko; sleep 1; dmesg | grep DF4522; kldunload df4522demo; host: sh static_proof.sh",
  "code_hash": "c706f1342f7794d9d5da49febd605cea531ee7b2b2c24443e482a377054dabb8",
  "notes": "Lead partially verified: leak REAL (dead-code proof airtight + on-kernel demo), infinite-loop hypothesis REFUTED (rb_leftmost is deterministically NULL via explicit LINUX_RB_ROOT_CACHED init at amdgpu_vm.c:3055; kzallocd fpriv amdgpu_kms.c:979). Root cause lives in the shared shim (rbtree.h cached macros ignore leftmost) but the only defect consumer in sys/ is amdgpu_vm.c:3325; all other rb_root_cached users (drm_mm.c:496, interval_tree_generic.h:60 users, i915_gem_userptr.c, radeon_mn.c) go through rb_first_cached which is a real RB_MIN walk on this port -- correct, just not O(1). amdgpu_mn.c:412 references undefined RB_ROOT_CACHED but is not in the module build. Normal GEM close empties the tree (amdgpu_gem.c:185 -> amdgpu_vm.c:2847-2859); leak requires the reserve-fail path (amdgpu_gem.c:170-175, deliberate upstream leak-for-fini-to-reclaim) or any still active bo inside vm state; KFD destroy cb is an empty stub (amdgpu_amdkfd.c:534). Guest was reset (vm.sh reset with-src) after evidence collection; guest source restored+sha256-verified before reset.",
  "recommended_fix": "Replace the dead rb_leftmost walk in amdgpu_vm_fini with a real tree walk: while (!RB_EMPTY_ROOT(&vm->va.rb_root)) { mapping = rb_entry(rb_first(&vm->va.rb_root), struct amdgpu_bo_va_mapping, rb); ... } (see fix.diff); alternatively restore the upstream postorder iterator, which this ports rbtree.h already provides (rbtree.h:135).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": null,
  "fix_patched_reproduced": null,
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 x86_64 (module-build validation only)",
  "fix_verdict": "fix.diff is validated at module-build level (baseline amdgpu.ko RC=0; patched amdgpu_vm.o recompiles clean under -Werror, module relinks, fix_build.log) and at semantics level on the running kernel (demo: fixed loop frees 64/64 on an identical tree where the verbatim loop freed 0). Full runtime validation on real amdgpu_vm_fini is impossible on this guest (no AMD GPU), hence not_testable rather than fixed. Guest source restored to pristine (sha256 7005b972...) after the patched build.",
  "fix_evidence": "fix_build.log (RC=0, amdgpu_vm.c recompile + amdgpu.ko relink); run.log FIXED fini loop: iterations=64 freed=64 LEAKED=0; git apply --check clean on host repo"
}