ttm_bo_vm_fault_dfly maps SG (prime-imported) foreign pages through the card node β the upstream TTM_PAGE_FLAG_SG refusal is dead code in #if 0
Summary
Upstream refuses to fault imported pages (redirecting mmap to the exporter); the live DFly fault has no such check: for prime-imported BOs it returns the exporter's ttm->pages into the importer's address space via the card-node mapping and mutates their cache attributes (pmap_page_set_memattr) with attributes chosen from the importer's placement - degrading coherency for every other mapping of those pages. Cross-driver cache-attribute DoS/coherency corruption via prime self-import. Port-the-SG-refusal fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4588 Β· 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.2 KB | β raw | |
| df4588.c | β | 2.3 KB | view raw | |
| verdict.json | β | 2.5 KB | view raw |
DF-4588 β ttm_bo_vm_fault_dfly maps SG (prime-imported) pages via the card node; upstream refusal check is dead code
File: sys/dev/drm/ttm/ttm_bo_vm.c β the DFly fault ttm_bo_vm_fault_dfly
(lines 499-725) has no TTM_PAGE_FLAG_SG refusal. Upstream's check
(bo->ttm && (bo->ttm->page_flags & TTM_PAGE_FLAG_SG) -> VM_FAULT_SIGBUS,
"Refuse to fault imported pages β¦ handled by redirecting mmap to the
exporter") sits dead inside the #if 0'd Linux body at lines 161-168.
Effect (radeon/amdgpu with prime import β wired on DFly: drm_ioctl.c:651-652, amdgpu_ttm.c:1272-1280 sets TTM_PAGE_FLAG_SG for imported BOs):
- The imported BO's
ttm->pagesare the exporter's pages. ttm_bo_vm_fault_dflyreturns them to the importer's address space (m = ttm->pages[OFF_TO_IDX(offset)], :690;*mres = m, :714) through the card node mapping instead of the exporter's mmap path.pmap_page_set_memattr(m, ...)(:695-697) andpmap_page_set_memattr(m, ttm_io_prot(...))(:669) mutate the cache attribute of pages the TTM layer does not own β affecting every other mapping of those pages (exporter's CPU mapping included).
Impact: cross-driver page-attribute mutation (cache-mode downgrade / coherency break for foreign mappings) + mapping imported pages through the wrong node with driver-chosen attributes. Linux deliberately refuses this fault (correctness + caching reasons); not kernel memory corruption by itself. Low severity, hardware-gated (needs radeon/amdgpu).
Fix
Port the upstream check into the live DFly fault:
--- a/sys/dev/drm/ttm/ttm_bo_vm.c
+++ b/sys/dev/drm/ttm/ttm_bo_vm.c
@@ -584,6 +584,14 @@ ttm_bo_vm_fault_dfly(vm_object_t vm_obj, vm_ooffset_t offset,
}
}
+ /*
+ * Refuse to fault imported (SG) pages; mmap of such objects
+ * must be handled by the exporter (upstream ttm_bo_vm_fault).
+ */
+ if (bo->ttm && (bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) {
+ retval = VM_PAGER_ERROR;
+ goto out_unlock1;
+ }
+
if (bdev->driver->fault_reserve_notify) {
PoC (df4588.c) is a documentation stub: the full trigger needs
amdgpu-specific GEM ioctls on real hardware. Untested on the audit
guest (no DRM device β same gate as DF-4587/DF-4458).
Fix verification
not_testableone-line port of the upstream check (README.md); not compile-validated separately β trivially contained in the same fault function rebuilt for DF-4587's fix (ttm_bo_vm.c compiles -Werror clean in drm.ko)
README.md diff hunk
Confirmed kernel references
Detail
Exploit chain
on amdgpu/radeon hardware: GEM_CREATE -> PRIME_HANDLE_TO_FD -> PRIME_FD_TO_HANDLE (self-import creates SG ttm_tt) -> GEM_MMAP ioctl -> mmap(card node, fake offset) -> touch -> foreign SG pages mapped with TTM-chosen attributes
Evidence (decisive lines)
README.md (code cites + ported upstream check); df4588.c (flow documentation)
PoC changes
no seed; documentation stub (full trigger requires amdgpu UAPI + hardware)
Verified recommended fix
Port the upstream TTM_PAGE_FLAG_SG refusal from the #if 0 body into ttm_bo_vm_fault_dfly (return VM_PAGER_ERROR before fault_reserve_notify)
Verdict
Upstream-divergence defect, certain in code, runtime hardware-gated: ttm_bo_vm_fault_dfly (ttm_bo_vm.c:499-725) lacks the upstream TTM_PAGE_FLAG_SG refusal (dead in #if 0 at ttm_bo_vm.c:161-168), so prime-imported BOs (TTM_PAGE_FLAG_SG set by amdgpu_ttm.c:1272-1280 / radeon_ttm.c:747; prime ioctls live at drm_ioctl.c:651-652) fault the exporter's pages through the card node and pmap_page_set_memattr mutates the cache attribute of pages TTM does not own (ttm_bo_vm.c:669,695-697). No kernel memory corruption by itself; cross-driver page-attribute/coherency impact. Not runnable on the audit guest (no DRM device); no runtime attempt made β PoC is a documentation stub plus the one-line port fix in README.md.
No comments yet.