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

vmap() computes allocation size in 32-bit arithmetic; large count overflows and maps count pages into undersized VA

Summary

size = count * PAGE_SIZE (line 55) multiplies unsigned int count by int PAGE_SIZE (1<<PAGE_SHIFT=4096). Product computed in 32-bit unsigned then zero-extended into size_t arg of kmem_alloc_nofault. When count >= 0x100000 (1M pages=4GiB) count*PAGE_SIZE wraps to small value (count=0x100000 gives size=0 count=0x100001 gives size=0x1000). kmem_alloc_nofault reserves only size bytes VA but line 62 stores unwrapped count into vmp->npages and line 63 pmap_qenter(off pages count) maps FULL count pages into PTEs starting at off -- mapping attacker-influenced physical pages far beyond allocated VA window and reading pages array OOB if caller array shorter than count. Mismatch between reserved VA and PTEs written corrupts adjacent kernel map entries and/or OOB read on pages caller array. Trigger: local user creates >=4GiB GEM object (DRM_IOCTL_I915_GEM_CREATE huge size permitted up to available memory) i915_gem_object_map -> vmap(pages n_pages...) with n_pages >= 0x100000. Resulting VA/PTE mismatch corrupts kernel page tables or triggers OOB read on pages array.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2189 Β· 2 files
FileTypeDescriptionSize
VERDICT.md file 740 B ↓ raw
fix.diff file 164 B view raw
VERDICT.md file
↓ download raw

DF-2189 - Verification Verdict

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

Verdict

Source-confirmed: vmap (:55) size=count*PAGE_SIZE in 32-bit unsigned; large count wraps to small allocation; pmap_qenter maps count pages into undersized VA; DRM-module-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/linux_vmalloc.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)

vmap 32-bit overflow; DRM-gated

Verified recommended fix

vmap 32-bit overflow; DRM-gated

Verdict

vmap 32-bit overflow; DRM-gated