# DF-4587 — ttm_bo_release_mmap unbalanced vm_object_deallocate → premature pager-object termination under live mappings (UAF)

File: `sys/dev/drm/ttm/ttm_bo_vm.c` (ttm_bo_release_mmap, lines 820–853)

## Build

Guest, any user:

```sh
cc -O2 -Wall -Wextra -o /tmp/df4587 /root/df4587.c    # BUILD_RC=0 expected
```

## Run

Guest, any user:

```sh
/tmp/df4587 /dev/dri/card0
```

## Expected

* **On radeon/amdgpu hardware** (the only DFly drivers setting `dev->drm_ttm_bdev`,
  radeon_ttm.c:913 / amdgpu_ttm.c:1796):
  1. 64 MiB dumb BO created in VRAM, mmap'd, one page faulted —
     the BO's OBJT_MGTDEVICE pager object now has **exactly one reference,
     owned by the map entry** (there is no handle-owned reference).
  2. VRAM pressure from further dumb BOs evicts the mapped BO
     (VRAM→GTT) → `ttm_bo_handle_move_mem` (ttm_bo.c:318-325) →
     `ttm_bo_unmap_virtual_locked` → **`ttm_bo_release_mmap`** →
     `vm_object_deallocate(vm_obj)` drops the *mapping's* reference:
     ref_count 1→0 → `vm_object_terminate` → `dev_pager_dealloc` →
     `ttm_bo_vm_dtor` → `ttm_bo_unref` — the pager object is FREED while
     the user's map entry still points at it, and the BO kref is dropped
     early.
  3. Re-touching the mapping re-faults through the **freed vm_object**
     (UAF read of `object->type`/`un_pager.devp.ops`, `vm_object_pip_add`
     write into freed memory); `munmap`/exit runs
     `vm_object_deallocate` on freed memory ("deallocated too many
     times" panic or silent corruption). If the mmap held the last BO
     kref, `ttm_bo_release` destroys the BO while
     `ttm_bo_handle_move_mem` keeps writing it.
* **On the audit QEMU guest** (bochs VGA 1111:1234, no /dev/dri, no drm
  modules): the trigger stops at the first gate — `open("/dev/dri/card0")
  == ENOENT` — exactly like DF-4458's run. The TTM code path is
  compile-reachable only; runtime is hardware-gated.

## Fix validation

`fix.diff` removes the unbalanced `vm_object_deallocate` and holds the
object across the revocation. Compile-validated on the guest by rebuilding
`drm.ko` (which compiles `ttm/ttm_bo_vm.c` via `.PATH`) with the fix —
see `build.log`. Behavioral before/after comparison impossible on this
guest (no TTM-capable GPU).
