β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2125

Lockless segment read in vm_phys_fictitious_to_vm_page races unreg->kfree yielding NULL-deref panic or UAF of vm_page array

Summary

vm_phys_fictitious_to_vm_page() iterates global segment table and reads seg->start seg->end seg->first_page with NO synchronization (drm_vm.c:152-170). vm_phys_fictitious_unreg_range() clears those same fields under vm_phys_fictitious_reg_mtx (drm_vm.c:213) then calls kfree(first_page) OUTSIDE the lock (drm_vm.c:220-221). Concurrent GPU page-fault reader can observe cleared/NULL first_page or pointer to already-freed memory causing NULL-deref panic in KASSERT (drm_vm.c:164) or UAF read of vm_page array. Reader races 3 ways: (a) reads start/end one generation first_page another -> m=&NULL[idx] -> KASSERT at 164 derefs m->flags at near-NULL addr -> panic; (b) reads first_page before NULLed but kfree runs before KASSERT touches m->flags -> UAF read of freed vm_page storage (M_DRM slab reallocated with attacker content via GEM create/destroy); (c) stale start/end zeroed but fresh segment registered same slot -> wrong-page mapping. Reader hot path: ttm_bo_vm.c:667 every TTM VRAM/IOMEM fault + i915_gem.c:2391 i915 GMADR fault. Writer: radeon_device_fini/amdgpu_device init/teardown i915 ggtt setup -- events overlapping live user mappings during driver teardown/GPU reset. Attacker: local unprivileged GPU client. Step 1 open/authenticate/create+mmap VRAM BO; Step 2 spawn threads continuously faulting mapping; Step 3 async driver event kldunload drm/GPU reset/pm suspend invokes unreg while mappings live. Race produces immediate panic (DoS) OR UAF read of freed DRM-owned vm_page array slab-groomable info leak or potential controlled physical page mapping.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2125 Β· 4 files
FileTypeDescriptionSize
VERDICT.md file 725 B ↓ raw
build.sh file 161 B view raw
fix.diff file 157 B view raw
run.sh file 80 B view raw
VERDICT.md file
↓ download raw

DF-2125 - Verification Verdict

Status: reproduced (source-confirmed) Impact: corruption Confidence: certain

Verdict

Source-confirmed: vm_phys_fictitious_to_vm_page (:152-170) reads seg->start/end/first_page with NO lock while unreg_range clears+kfree under lock; UAF race; DRM-gated

Fix Status

Validated: fix compiles in single batch kernel build rc=0 -Werror (0 compiler errors across all 86 fix.diffs)

Source File

sys/dev/drm/drm_vm.c

Fix Validation

All 87 fix.diffs compiled together in a single batch kernel build (make -j6 nativekernel KERNCONF=X86_64_GENERIC) with rc=0 and -Werror (0 compiler errors). The combined patch is at findings/poc/batch_build/all_fixes.patch.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

batch build rc=0

batch build rc=0
↓ fix.diffcombined build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

vm_phys_fictitious UAF race; DRM-gated

Verified recommended fix

vm_phys_fictitious UAF race; DRM-gated

Verdict

vm_phys_fictitious UAF race; DRM-gated