# DF-3792 VERDICT

**Status: inconclusive** (runtime verification impossible on this guest — no
DRM device; also no in-tree trigger exists). **Severity: Info (hardening).**
**Confidence: certain** that the divergence exists (direct diff against
upstream fix commits `fe6169288666` and `26564be56d73`).

## Narrative

Pass-2 diff of `sys/dev/drm/drm_atomic_helper.c` (4021 LOC) against upstream
v4.19/v5.0/v5.1/v5.2/v5.4 references shows the local file is an ~v5.0-rc
snapshot minus several later fixes. Three unguarded callback dereferences
were fixed upstream after this snapshot:

1. `disable_outputs()` CRTC loop — local `sys/dev/drm/drm_atomic_helper.c:1007-1014`:
   `prepare`/`atomic_disable`/`disable` all NULL → falls into
   `funcs->dpms(crtc, DRM_MODE_DPMS_OFF)` **with dpms possibly NULL** →
   call through NULL → panic. Upstream `fe6169288666` (v5.2 window) changed
   the tail to `else if (funcs->dpms)`.
2. `commit_modeset_enables()` CRTC loop — local `:1253-1260`:
   `atomic_enable` NULL → `funcs->commit(crtc)` **with commit possibly
   NULL**. Same upstream fix added `else if (funcs->commit)`.
3. `mode_fixup()` — local `:461-463` reads `funcs->mode_fixup` with
   `funcs = crtc->helper_private` possibly NULL (upstream `26564be56d73`
   added `!funcs ||`). Same NULL-funcs exposure at `:1007`
   (`new_crtc_state->enable && funcs->prepare`).

These are NULL function-pointer *calls* (page-fault/panic), not attacker-
controlled IP — no exploitation path beyond DoS, and then only for a driver
that registers a CRTC with a partial `drm_crtc_helper_funcs` table and uses
the generic `drm_atomic_helper_commit()` machinery.

## In-tree reachability: exhaustively checked, none

* i915 `intel_helper_funcs` (`intel_display.c:10939-10944`) is exactly the
  partial table that would trigger it — but i915 uses its own
  `intel_atomic_commit`/`intel_atomic_commit_tail` (`intel_display.c:12787`)
  which never call `disable_outputs()`/`commit_modeset_enables()`.
* amdgpu_dm has its own commit tail (`amdgpu_dm.c:4733`) and its CRTC helper
  table sets `.disable` (`amdgpu_dm.c:3403-3407`).
* classic amdgpu DCE tables all set `.dpms/.disable/.commit`
  (e.g. `dce_v8_0.c:2562-2571`), and classic amdgpu is legacy-helper based.
* radeon is legacy-crtc-helper based (never reaches the atomic commit path).

Conclusion: **Info** — the guards protect against future/out-of-tree drivers;
upstream treats them as required robustness (both commits are merged fixes).

## Why inconclusive at runtime

Guest has QEMU std VGA only (`pciconf`: `chip=0x11111234`), no virtio_gpu
driver in the DFly tree, `drm.ko` not loaded, `/dev/dri` absent — no DRM
device exists to exercise any path in this file (full survey in
`findings/poc/DF-3791/env.txt`).

## Exploit chain

None (NULL callback dispatch = panic at worst; no control over the called
address).

## Recommended fix

Apply `fix.diff` (backport of the three upstream guards).

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