# DF-4437 VERDICT — certain code defect, latent trigger on stock DF

## Reproduced?
No runtime verification performed (status: untested). Two independent
blockers on the audit guest: (1) no DRM device exists in the guest
(`/dev/dri` absent, only an unbound QEMU std-VGA chip — env.txt); (2) the
leak needs a `page_flip_target`-capable driver (radeon / pre-DC amdgpu)
raced by a ww-modeset-lock-inversion producer, which stock DragonFly
does not currently ship for those drivers. Low severity, non-trivial
local trigger ⇒ QEMU verification not mandated by the audit contract.

## Why the logic defect is certain (control-flow proof)
`sys/dev/drm/drm_plane.c`, `drm_mode_page_flip_ioctl`:

- `:1049-1055` if `crtc->funcs->page_flip_target`:
  `r = drm_crtc_vblank_get(crtc);` — reference taken exactly once,
  BEFORE `drm_modeset_acquire_init()` at `:1088`, i.e. outside the retry
  loop.
- `:1088-1089` `drm_modeset_acquire_init(...); retry:`
- `:1179` `out:` … `:1186-1190`
  `if (ret == -EDEADLK) { ret = drm_modeset_backoff(&ctx); if (!ret) goto retry; }`
- `:1195-1196` `if (ret && crtc->funcs->page_flip_target)
  drm_crtc_vblank_put(crtc);`

Trace: iteration 1 returns -EDEADLK (from `drm_modeset_lock` at
`:1090/:1093` or the driver callback at `:1160/:1165`) → `out:` →
EDEADLK branch → `goto retry` (skipping the put at `:1195`) → iteration
2 succeeds → `ret == 0` → the `ret &&` guard makes the put a no-op →
the vblank reference acquired at `:1053` is never released. One leaked
reference per successfully retried flip; repeatable per contention
event.

This tail is byte-identical in Linux v5.0 (the DF copy's origin) and in
upstream master as of 2026-09 — the defect is upstream-inherited and
still latent upstream.

## Reachability analysis (what keeps this at Low)
- Gate: DRM_IOCTL_MODE_PAGE_FLIP is DRM_MASTER-gated
  (`sys/dev/drm/drm_ioctl.c:673`). Unprivileged reach requires the
  attacker to BE the master (possible on a headless/console box where
  they win DRM_IOCTL_SET_MASTER) or to be the compositor.
- Live drivers: radeon (`sys/dev/drm/radeon/radeon_display.c:666`) and
  amdgpu legacy DCE v8/v10/v11/virtual
  (`sys/dev/drm/amd/amdgpu/amdgpu_display.c:146`) implement
  `page_flip_target`; DC-based amdgpu does not.
- EDEADLK producer: this ioctl takes crtc->mutex then plane->mutex.
  Every in-tree core path (setplane lock_all, cursor ioctl, atomic
  check, setcrtc) uses the same crtc-before-plane order, so no ww cycle
  is generated with them; `drm_atomic_helper_update_plane` (which locks
  plane state before crtc state, creating a real inversion) exists only
  in atomic drivers that don't carry `page_flip_target`. Conclusion: on
  stock DF the trigger currently has no producer; the defect becomes
  exploitable the day such a producer is compiled in. Confidence
  "likely" (defect certain, trigger latent).

## Impact ceiling
Per leaked reference: `vblank->refcount` grows by one and the vblank IRQ
can never be disabled for that CRTC (idle-power/perf regression, warn
spam on counter saturation after ~2^31 events). No kernel memory
corruption, no info leak. Local display-subsystem DoS at worst.

## Fix validation
Not applicable (no runtime repro). `fix.diff` brackets the reference
with a `vblank_ref_held` flag so every exit path and every retry pairs
get/put exactly once.

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