{
  "finding_id": "DF-4521",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "drm_mm_for_each_node_in_range() hands the unallocated head_node sentinel to the callers loop body and never terminates when end > mm end; reproduced live with the real kernel drm_mm.c in a kld: a top-of-GTT eviction walk (i915_gem_evict_for_nodes exact parameters) yielded allocated=0 head sentinel at visit 2 and wrapped forever (visited=8 capped, non_terminating=1). The downstream i915 arm (container_of fake i915_vma -> i915_vma_unbind -> drm_mm_remove_node(sentinel)) was simulated at the drm_mm level and demonstrably wipes the interval tree (range query over an allocated nodes own range returns zero nodes) and plants a size-underflowed hole (0xffffffff10000000) into the hole trees. Full unprivileged execbuf2 (EXEC_OBJECT_PINNED) trigger is source-traced hop-by-hop but hardware-gated: guest has no Intel GPU.",
  "exploit_chain": "execbuf2 EXEC_OBJECT_PINNED at offset=vm.total-size (no gen gate, execbuffer.c:461) -> i915_vma_pin PIN_OFFSET_FIXED -> i915_gem_gtt_reserve (gtt.c:3949) -> drm_mm_reserve_node -ENOSPC -> i915_gem_evict_for_node with check_color end+=4K (evict.c:296) -> drm_mm_for_each_node_in_range walks past last node onto head sentinel -> (a) livelock under struct_mutex (DoS), or (b) container_of(head) fake vma (GEM_BUG_ON compiled out) -> pin/list_add -> i915_vma_unbind -> drm_mm_remove_node(head_node) -> interval tree root wiped (RB_REMOVE of never-inserted node) + underflowed hole -> blind overlap checks -> GTT aliasing / list corruption on wrap passes",
  "evidence": "run.log visits 1-8 (HEAD SENTINEL at visit 2, RESULT non_terminating=1); corrupt.log probes (mid node invisible to its own range query; bogus hole [0x100000000,0x10000000) size ffffffff10000000); run.fixed.log (visited=1, no sentinel, terminates); dmesg.txt full console",
  "kernel_refs": [
    "sys/dev/drm/drm_mm.c:171-176",
    "sys/dev/drm/include/drm/drm_mm.h:483-502",
    "sys/dev/drm/i915/i915_gem_evict.c:292-336",
    "sys/dev/drm/i915/i915_gem_gtt.c:3949-3975",
    "sys/dev/drm/i915/i915_gem_gtt.c:3638-3639",
    "sys/dev/drm/i915/i915_gem_execbuffer.c:461-463",
    "sys/dev/drm/i915/i915_gem_execbuffer.c:614-615",
    "sys/dev/drm/i915/i915_vma.c:687-695",
    "sys/dev/drm/i915/i915_gem.h:60",
    "sys/dev/drm/include/linux/bug.h:45",
    "sys/dev/drm/include/linux/rbtree.h:101-102"
  ],
  "poc_changes": "PoC authored fresh (no seed): kld embeds unmodified /usr/src/sys/dev/drm/drm_mm.c + real drm_mm.h macros; local RB_GENERATE(linux_root)/panic_cmp/drm_printf stubs were needed because those live in the not-loaded drm.ko; sysctl-triggered scenarios with iteration cap to make non-termination observable without hanging the guest",
  "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": 2400,
  "guest_dirty": 1,
  "build_cmd": "cd /tmp/DF-4521 && cp /usr/src/sys/dev/drm/drm_mm.c . && make",
  "run_cmd": "kldload ./dfmm_poc.ko && sysctl dev.dfmm.run=1  (scenario 2: sysctl dev.dfmm.corrupt=1)",
  "code_hash": "9b8283d18d06a376806e0ce586ee24eff27028453f77b7202fabee677ae96b77",
  "notes": "Guest lacks Intel GPU (Bochs vga chip 0x11111234) so the end-to-end ioctl trigger is hardware-gated; drm_mm-level defects (sentinel yield, non-termination, interval-tree wipe, underflow hole) all executed live with real kernel code. No panic: kernel survived sentinel remove with corrupted allocator state (proof in corrupt.log). Inherited from Linux 4.12-era code; i915 no longer uses this path with unclamped end in modern upstream. Guest left dirty (kld + /usr/src patch) and reset with-src afterwards.",
  "recommended_fix": "Stop drm_mm_for_each_node_in_range at the head_node sentinel (drm_mm.h) and clamp i915_gem_evict_for_nodes color-expanded end to vm->total",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff applied to guest /usr/src/sys (drm_mm.h iterator sentinel stop + i915 evict end clamp), kld rebuilt from same real sources, identical PoC re-run: baseline visited=8/head_sentinel_yielded=1/non_terminating=1 vs patched visited=1/head_sentinel_yielded=0/non_terminating=0 (run.fixed.log). Bad behavior gone; in-range iteration semantics unchanged.",
  "fix_evidence": "run.fixed.log last lines: visit 1: start=fffff000 ... allocated=1 then RESULT: visited=1 head_sentinel_yielded=0 non_terminating=0; patch transcript in session (patch -p0: Hunk #1 succeeded at 492 / Hunk #1 succeeded at 308)"
}