# VERDICT — DF-5783

**Status: untested** (no Intel GPU on the audit rig; verified by line-level
static analysis + upstream differential). **Impact ceiling: local DoS /
persistent display-engine state corruption (underruns, hung pipe, cursor left
scanning on a disabled pipe), by a DRM master.** Not memory corruption: the
corrupted value is a plane bitmask inside the committed crtc state.

## Proven chain

1. `intel_legacy_cursor_update()` — `sys/dev/drm/i915/intel_display.c:13623`
   fast path (taken when crtc active, no modeset pending: :13644-13646).

2. `:13686-13689` passes the **live committed crtc state twice**:
   ```c
   ret = intel_plane_atomic_check_with_state(to_intel_crtc_state(crtc->state),
                                             to_intel_crtc_state(crtc->state), /* FIXME need a new crtc state? */
                                             to_intel_plane_state(plane->state),
                                             to_intel_plane_state(new_plane_state));
   ```

3. `intel_plane_atomic_check_with_state()` mutates its `crtc_state` argument:
   `sys/dev/drm/i915/intel_atomic_plane.c:129-132`
   ```c
   if (state->visible)
           crtc_state->active_planes |= BIT(intel_plane->id);
   else
           crtc_state->active_planes &= ~BIT(intel_plane->id);
   ```
   A cursor-off request therefore clears `PLANE_CURSOR` from the LIVE
   `crtc->state->active_planes`.

4. Failure exits come after the mutation and do not roll it back:
   `mutex_lock_interruptible()` :13693 (`-EINTR`, signal-raceable) and
   `intel_plane_pin_fb()` :13697 (pin failure) both bail via
   `out_unlock`/`out_free` (:13722-13729) while the hardware cursor is still
   enabled. State now says "no cursor", hardware says "cursor on".

5. Upstream fixed exactly this in v5.0, commit `c249c5f64336` ("Handle
   cursor updating active_planes correctly, v2."): "we may clear
   active_planes if the new cursor update state will disable the cursor, but
   we fail after. If this is immediately followed by a modeset disable, we
   may soon not disable the planes correctly when we start depending on
   active_planes." The v2 note also documents the concurrent page-flip/
   atomic-commit hazard of touching the live state. Downstream consumers of
   the stale bit in this tree: plane-disable decisions,
   `hsw_compute_ips_config` (intel_display.c:6666 — IPS with no planes),
   watermark recomputation (intel_pm.c) → underrun/hung-display class
   failure.

## Threat bound (honest)
* `DRM_IOCTL_MODE_CURSOR`/`MODE_CURSOR2` are `DRM_MASTER|DRM_UNLOCKED`
  (`sys/dev/drm/drm_ioctl.c:659,680`) — the trigger needs DRM master.
  On DragonFly there is no logind-style master handoff; any local user who
  can open the device while no master exists can call
  `DRM_IOCTL_SET_MASTER` unprivileged (standard "untrusted master" model
  upstream also treats as a security boundary for cursor bugs).
* Requires Intel i915 hardware; absent on this rig (Bochs VGA), hence
  untested runtime, static+differential proof only.

## Fix
Backport of `c249c5f64336` essence: duplicate the crtc state, run the check
against the duplicate, and copy only `active_planes` back into the live
state on full success (never on failure). See `fix.diff`.

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