⬢ DragonFlyBSD Kernel Audit
DF-5186 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5186",
  "status": "inconclusive",
  "verdict": "Code-certain race, target-device-absent on this guest. drm_mode_mmap_dumb_ioctl is dispatched DRM_UNLOCKED|DRM_RENDER_ALLOW (drm_ioctl.c:676, invoked locklessly at drm_ioctl.c:777); the i915 override (.dumb_map_offset=i915_gem_mmap_gtt, i915_drv.c:3301 -> i915_gem.c:2600-2602) and the GEM default both reach drm_gem_create_mmap_offset_size (drm_gem.c:567-606), whose on_map/map_list.key/drm_ht_insert_item/idxunr publication has no synchronization, while the same hash is the authoritative mmap resolver under DRM_LOCK (drm_gem.c:1063-1109). Two barrier-synced MAP_DUMB calls on one fresh handle deterministically corrupt state (proved by the 1:1 kernel transliteration in sim_interleave.c: live-key free_unr + teardown double-free => index aliasing; same drm_hash_item linked into two buckets => drm_ht_find_item returns the wrong object => cross-object/UAF mapping via drm_gem_mmap_single). The QEMU audit guest has no DRM device (std-VGA, no /dev/dri, no drm kld, no vgem in-tree), so the kernel path cannot be entered: PoC builds clean (cc 8.3) and runs, exiting 2 with no /dev/dri node available (run.log). Ready to run on any i915/amdgpu/radeon DragonFly box; smoking gun = MAP_DUMB EINVAL + [drm:drm_gem_create_mmap_offset_size] *ERROR* failed to add to map hash.",
  "reproduced": false,
  "impact": "none",
  "confidence": "likely",
  "exploit_chain": "video-group user opens /dev/dri/card0 (0660 root:video, drm_drv.c:1178) -> CREATE_DUMB (no auth) -> two threads barrier-synchronized MAP_DUMB on the fresh handle, with create/destroy churn recycling idxunr -> corrupted offset_hash (double free_unr / dual-linked node) -> mmap(card0_fd, KEY|OFF(idx)) resolving an aliased or dangling entry -> wrong-or-freed GEM object mapped: cross-process GPU-buffer disclosure or UAF-class RW mapping. Ceiling not demonstrated: needs DRM hardware this guest lacks.",
  "evidence": "run.log (PoC exit 2 - no /dev/dri on guest), sim_output.txt (deterministic interleaving A: live-key free + double free_unr + index aliasing; interleaving B: same node in two buckets + drm_ht_find_item(1) returns objA -> wrong-object resolution), env.txt (guest uname/kldstat/no-dri), build.log, VERDICT.md full path trace",
  "kernel_refs": [
    "sys/dev/drm/drm_dumb_buffers.c:115-130",
    "sys/dev/drm/drm_ioctl.c:676",
    "sys/dev/drm/drm_ioctl.c:777",
    "sys/dev/drm/drm_gem.c:567-606",
    "sys/dev/drm/drm_gem.c:529-546",
    "sys/dev/drm/drm_gem.c:1063-1109",
    "sys/dev/drm/drm_hashtab.c:109-133",
    "sys/dev/drm/i915/i915_drv.c:3301",
    "sys/dev/drm/i915/i915_gem.c:2600-2648"
  ],
  "poc_changes": "n/a (seed written from scratch in this run; self-contained uapi defs because the guest ships no drm headers; pair-barrier churn design so the race hits the first-MAP_DUMB window of every fresh object)",
  "attempts": 3,
  "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": 95,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -pthread -o mapdumb_race mapdumb_race.c && cc -O2 -Wall -o sim_interleave sim_interleave.c",
  "run_cmd": "./mapdumb_race 20000 && ./sim_interleave",
  "code_hash": "8d39eec92884fbf04a65c9726e6f48a2a7beda12c59e418f83f7f8a3a7f989de",
  "notes": "DRM device nodes are root:video 0660 (drmP.h:108-110) - a standard desktop user qualifies. All three in-tree KMS drivers override .dumb_map_offset but i915s override still funnels into the vulnerable drm_gem_create_mmap_offset. In-file drm_mode_create_dumb size math audited correct (64-bit checks at drm_dumb_buffers.c:64-80; PAGE_ALIGN wrap caught on 32-bit). Guest left clean (files under /root/df5186 and /tmp/df5186_race only; no kernel state touched).",
  "recommended_fix": "Serialize drm_gem_create_mmap_offset_size/drm_gem_free_mmap_offset legacy offset-hash publication with dev->object_name_lock (sleepable, LK_CANRECURSE) - see fix.diff",
  "fix_status": "not_applicable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "Baseline cannot be exercised on this guest (no DRM device), so a patched-kernel A/B run is impossible here; fix.diff is line-accurate against drm_gem.c:529-588 and must be validated on DRM hardware (with the patch, concurrent MAP_DUMB can never lose the insert race, so no live-key free_unr / dual-link).",
  "fix_evidence": "fix.diff"
}