# DF-4329 — verdict: REPRODUCED (sequenced protocol replica on live kernel)

## Root cause (path:line)
- sys/dev/drm/include/linux/rcupdate.h:94-96 — `#define synchronize_rcu()`
  (EMPTY), `cond_synchronize_rcu(x)` -> cpu_mfence(), `get_state_synchronize_rcu()`
  -> 0; rcu_read_lock() == preempt_disable(). No grace periods exist anywhere
  in the port.
- sys/dev/drm/include/linux/slab.h:53-107 — SLAB_TYPESAFE_BY_RCU is defined
  but ignored; kmem_cache_alloc() == kmalloc(size, M_DRM) from the generic
  per-type zone shared by every drm allocation; kmem_cache_free() == kfree().
- sys/dev/drm/include/linux/dma-fence.h:98-103 — dma_fence_get_rcu() uses
  plain kref_get() (unconditional increment) instead of kref_get_unless_zero.
- sys/dev/drm/i915/i915_request.c:732-761 — i915_request_alloc()'s
  "dragons" protocol explicitly depends on all three (comment: "we chase the
  request->engine pointer"); its OOM backpressure path (:738-741) waits for
  readers with cond_synchronize_rcu(rq->rcustate) — a no-op fence on DFly.
- Reader: sys/dev/drm/i915/i915_request.h:514+ __i915_gem_active_get_rcu()
  -> i915_request_completed() -> i915_request.h:318-322
  `intel_engine_has_completed(rq->engine, seqno)` — dereferences the chased
  pointer; reachable unprivileged via i915_gem_busy_ioctl (i915_gem.c:4971+).

## What was proven on the guest
Mode 1 (run.log): (a) freed 392-byte "request" chunk instantly REUSED by an
unrelated same-zone kmalloc (same address 0xfffff8004f309140) — no grace
period, typesafe semantics unenforced; (b) dma_fence_get_rcu replica
resurrects refcount 0->1; (c) the stale reader (under the port's
rcu_read_lock == crit_enter) sees the stale tracker pointer, reads
global_seqno 0x42 and chases the planted engine marker.
Mode 2 (panic.txt): the reader protocol actually dereferences the marker:
"Fatal trap 12 ... fault virtual address = 0x515151515169, Stopped at
run_replica+0x350: movl 0x18(%r12),%esi" — kernel fault on a fully
attacker-chosen address via the exact upstream reader code path.

The replica is sequenced (deterministic); on real hardware the same state is
reached by any interleaving in which a reader is between
rcu_dereference(active->request) and the engine chase while the request
retires, frees, and the chunk is reallocated+filled — exactly the window the
upstream protocol exists to close. Reachability: unprivileged GL client
(GEM_BUSY hammering) + request alloc/free churn; race window widened by
memory pressure (the very path whose barrier is a no-op).

## Impact
On Intel-GPU systems: stale-reader UAF — wild-pointer dereference of
attacker-influenced reused-object contents (demonstrated: fault on chosen
address) plus foreign refcount corruption (0->1 resurrection / stray puts).
Realistic ceiling: kernel memory corruption/panic from unprivileged local
GPU client; full uid=0 chain not attempted (no i915 GPU on the audit guest —
hardware-gated) — the demonstrated primitive (chosen-address kernel read
fault, refcount corruption at chosen offsets) is the standard substrate for
escalation.

Related but distinct: DF-1881 (same broken dma_fence_get_rcu shim, but the
reservation-object readers in linux_reservation.c — different file/sink).
This finding covers the i915_request.c/i915_request.h request-slab protocol
including the allocator/grace-period layers DF-1881 does not touch.

## Fix
fix.diff: map the shim's rcu macros to DragonFly's native RCU and make
dma_fence_get_rcu refuse dead refcounts. (Full typesafe-cache semantics for
kmem_cache would additionally require an objcache-backed implementation; the
grace-period + get_unless_zero fixes restore the reader protocol's safety
for same-object reuse.)
## Fix validation
fix_status=not_testable: the fix edits drm shim headers compiled into the
drm.ko/i915 module set; no Intel GPU exists on the guest to load i915.ko,
and rebuilding the full drm stack to re-run the replica would validate the
replica, not the driver path.

## 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.
