⬢ DragonFlyBSD Kernel Audit
DF-4459 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4459",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Code defect certain, OOM-gated: drm_gem_init (drm_gem.c:130-163) kzallocs mm (139) and vma_offset_manager (140) but NULL-checks only vma_offset_manager (141). If mms allocation fails, drm_ht_create(&mm->offset_hash, 12) (148) dereferences &NULL->offset_hash -> panic; unprivileged memory pressure can induce GFP_KERNEL failure but the site runs at drm device registration, so the practical window is OOM coinciding with a drm load. On the !vma_offset_manager path mm is leaked; on the drm_ht_create failure path dev->mm_private (assigned at 146, before the failure point) kfrees mm at 149 without being cleared, leaving a stale pointer that drm_gem_destroy (170-171) and every drm_gem_create_mmap_offset_size (570, 576-577) later dereference (UAF), and vma_offset_manager is leaked there too. Upstream FreeBSD checks both allocations; the port dropped the mm check and reordered the assignment. Not runtime-reproducible on the audit guest (no OOM injection site, no drm hardware; force-loading drm.ko without hardware wedges the loader) \u2014 defect proven by static verification (run.log) with all hops cited in VERDICT.md.",
  "exploit_chain": "",
  "evidence": "run.log (grep script output confirming 139/141 asymmetry, 146-before-149 dangling assignment, 170-171 downstream derefs); build.log (drm.ko rebuilt with fix, -Werror, DRM_BUILD_RC=0); fix.diff (git apply --check OK)",
  "kernel_refs": [
    "sys/dev/drm/drm_gem.c:139",
    "sys/dev/drm/drm_gem.c:141",
    "sys/dev/drm/drm_gem.c:146",
    "sys/dev/drm/drm_gem.c:149",
    "sys/dev/drm/drm_gem.c:170"
  ],
  "poc_changes": "no seed; static-verification script authored for the pack",
  "attempts": 1,
  "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": 120,
  "guest_dirty": 0,
  "build_cmd": "cd /usr/src/sys/dev/drm/drm && make obj && make   (patched, guest cc 8.3, -Werror, RC=0)",
  "run_cmd": "sh run.sh sys/dev/drm/drm_gem.c",
  "code_hash": "",
  "notes": "Adjacent noted-but-not-filed: drm_gem_destroy does not idr_destroy(&dev->object_name_idr) (cached radix nodes leak at device teardown) \u2014 folded into this findings area, not separately actionable. Guest /usr/src restored pristine; guest up.",
  "recommended_fix": "NULL-check both kzallocs, free both on any failure, and assign dev->mm_private only after drm_ht_create() succeeds",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff (git apply --check OK) checks both allocations, frees both on failure, and moves dev->mm_private assignment after drm_ht_create success. Compile-validated on the guest: drm.ko rebuilt with the fix, -Werror, RC=0 (build.log). Behavioral runs impossible: OOM-injection at this site is not available on the guest and there is no drm hardware (fix_status not_testable, compile-validated).",
  "fix_evidence": "fix.diff; build.log (patched drm.ko full -Werror compile+link, DRM_BUILD_RC=0); VERDICT.md Fix validation"
}