Default drm_gem_dumb_map_offset returns offsets from the wrong address space: vma-manager address without DRM_GEM_MAPPING_KEY bits, unresolvable by (and unrelated to) the hash-key mmap path β latent (no in-tree caller)
Summary
Two disjoint offset namespaces grafted onto one file: the default handler reads the vma-manager address while the mmap resolver consumes only the idxunr hash-key form - any driver relying on the default hands users unresolvable offsets (and the split empowers DF-5186). All three KMS drivers override today. Return-the-hash-key-form fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-5187 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.2 KB | β raw | |
| VERDICT.md | β | 2.0 KB | β raw | |
| fix.diff | β | 603 B | view raw | |
| manifest.json | β | 659 B | view raw | |
| verdict.json | β | 2.2 KB | view raw |
DF-5187 β default drm_gem_dumb_map_offset returns offsets from the wrong address space (latent, dead in-tree)
What
The default drm_gem_dumb_map_offset (reached from
drm_mode_mmap_dumb_ioctl's else branch, sys/dev/drm/drm_dumb_buffers.c:128)
returns
*offset = drm_vma_node_offset_addr(&obj->vma_node); /* drm_gem.c:401 */
the raw vma-offset-manager address (drm_mm region starting at
DRM_FILE_PAGE_OFFSET_START = 0x100000 pages = 1<<40 bytes β drm_gem.c:119-160).
But the DragonFly mmap resolver for the DRM cdev only understands the legacy
hash-key form:
if ((offset & DRM_GEM_MAPPING_MASK) != DRM_GEM_MAPPING_KEY) /* 2ULL<<62 */
return (NULL); /* drm_gem.c:1070 */
offset &= ~DRM_GEM_MAPPING_KEY;
drm_ht_find_item(&mm->offset_hash, DRM_GEM_MAPPING_IDX(offset), ...)
and the hash key lives in a different allocator (mm->idxunr,
drm_gem.c:153) than the vma node's page index β two independent namespaces
grafted together in this port. i915's own override returns the correct form
(DRM_GEM_MAPPING_OFF(obj->base.map_list.key) | DRM_GEM_MAPPING_KEY,
i915_gem.c:2647-2648), which is what everything actually uses.
Consequences for any driver relying on the default:
- the MAP_DUMB offset lacks the KEY bits β
mmap()on it returnsENODEV(dumb buffers unmap-able β functional bug); - nothing in the default path establishes the correspondence the resolver assumes (vma page index vs idxunr key), so the two namespaces can disagree about which object an offset denotes β the same mis-wiring that gives DF-5186's race its wrong-object resolution power.
Scope
Latent: all three in-tree KMS drivers override .dumb_map_offset
(amdgpu_drv.c:1322, i915_drv.c:3301, radeon_drv.c:693), so no in-tree path
uses the default. Info severity; filed so the port's dual-namespace mmap
plumbing is on record and because any out-of-tree/currently-unwired GEM driver
that trusts the default hands out unmappable (or mis-resolving) offsets.
Fix
Return the hash-key form exactly like i915 (fix.diff). Not verified at
runtime (no in-tree consumer; no DRM device on the audit guest) β hence
status untested.
DF-5187 β VERDICT
status: untested Β· Info/latent β no PoC attempted (no in-tree consumer of the default path; no DRM device on the audit guest).
Code facts (all verified by reading this tree):
drm_mode_mmap_dumb_ioctlfalls back todrm_gem_dumb_map_offsetwhen the driver does not override (sys/dev/drm/drm_dumb_buffers.c:120-129).drm_gem_dumb_map_offsetreturns the vma-manager address (sys/dev/drm/drm_gem.c:401); that address space starts atDRM_FILE_PAGE_OFFSET_START= 0x100000 pages (drm_gem.c:119-123,158-160) and carries noDRM_GEM_MAPPING_KEYbits.- The cdev mmap path
drm_mmap_singleβdrm_gem_mmap_singleβdrm_gem_object_from_offset(drm_drv.c:1256-1270, drm_gem.c:1063-1080) rejects offsets without the KEY bits (ENODEV) and resolves the index through the separatemm->idxunrkey space (drm_gem.c:153,576). - i915's override returns the resolver-compatible form
DRM_GEM_MAPPING_OFF(map_list.key) | DRM_GEM_MAPPING_KEY(i915_gem.c:2647-2648) β proof that the two namespaces are distinct and only the hash-key form works. - In-tree users of the default: none (
.dumb_map_offsetset by amdgpu_drv.c:1322, i915_drv.c:3301, radeon_drv.c:693).
Conclusion: real mis-wiring, currently dead in-tree, actionable one-line fix (fix.diff). No runtime verification performed β nothing to run against.
kernel_refs
- sys/dev/drm/drm_dumb_buffers.c:120-129 (audited-file fallback)
- sys/dev/drm/drm_gem.c:381-406 (default handler)
- sys/dev/drm/drm_gem.c:1063-1080 (resolver requiring KEY|OFF(hash key))
- sys/dev/drm/drm_gem.c:119-160 (two disjoint offset allocators)
- sys/dev/drm/i915/i915_gem.c:2647-2648 (working override form)
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableNot applicable - latent dead-in-tree path; nothing to A/B on this guest.
fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md (full path trace with line cites); fix.diff (one-line correction matching i915_gem.c:2647-2648)
PoC changes
n/a (Info finding, no PoC attempted per Phase V skip rule for Low/Info)
Verified recommended fix
Return DRM_GEM_MAPPING_OFF(obj->map_list.key) | DRM_GEM_MAPPING_KEY from drm_gem_dumb_map_offset (see fix.diff)
Verdict
Latent mis-wiring, code-verified, not exercised: the DEFAULT drm_gem_dumb_map_offset (drm_dumb_buffers.c:128 -> drm_gem.c:401) returns the raw vma-offset-manager address (no DRM_GEM_MAPPING_KEY bits, drm_gem.c:119-160) while the DragonFly DRM mmap resolver drm_gem_object_from_offset (drm_gem.c:1063-1080) only accepts KEY|OFF(idxunr-hash-key) offsets resolved via the legacy offset_hash - a disjoint allocator. Any driver relying on the default hands out offsets that mmap() rejects with ENODEV, and the two offset namespaces disagree on object identity. All three in-tree KMS drivers override .dumb_map_offset (amdgpu_drv.c:1322, i915_drv.c:3301, radeon_drv.c:693), so no in-tree path uses the default; the audit guest additionally has no DRM device. One-line fix mirrors i915's working form (fix.diff). Info severity.
No comments yet.