DF-4459 / verdict.json
{ "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" } |