# DF-4205 VERDICT

**Status: untested (Phase V skipped — Low severity, firmware/OOM-gated, no
Intel GPU on the audit guest). Bug existence: certain, proven from source.**

## Root cause

`vlv_dsi_init()` decides DSI is present from the VBT *child device list*
(`intel_bios_is_dsi_present`, intel_bios.c:2034-2047), but then dereferences
`dev_priv->vbt.dsi.config` (vlv_dsi.c:1797 `->dual_link`, :1826 `->pwm_blc`)
which is only populated when a *different* BDB section (`BDB_MIPI_CONFIG`)
exists AND both kmemdups succeed (intel_bios.c:826-856). The two presence
signals are decoupled; there is no guard at the consumer.

Three concrete failure inputs:

1. **NULL deref (panic)** — VBT has a MIPI child device but no
   `BDB_MIPI_CONFIG` section: `find_section()` returns NULL
   (intel_bios.c:826-830), `dsi.config` stays NULL, `vlv_dsi_init` runs to
   :1797 and faults on the NULL page. Kernel panic at i915 attach.
2. **NULL deref (OOM)** — `kmemdup(config)` fails (intel_bios.c:843-845):
   config stays NULL, same fault at :1797.
3. **UAF read** — `kmemdup(pps)` fails after config succeeded
   (intel_bios.c:847-851): `kfree(dsi.config)` leaves the pointer dangling;
   vlv_dsi.c:1797 reads `dual_link` from freed memory (1 byte), then
   `intel_dsi_vbt_init()` parses the entire freed `struct mipi_config`
   (intel_dsi_vbt.c:506,523-544) and vlv_dsi.c:1826 reads `pwm_blc`.

## Why not verified on the guest

* The audit QEMU guest exposes no Intel GPU; i915 does not attach, so
  `vlv_dsi_init` is unreachable by construction (not_testable conditions).
* Even on hardware, the trigger is firmware content (VBT) or a specific OOM,
  neither of which an unprivileged guest user controls.
* Severity Low → contract exempts from Phase V.

## Impact ceiling

Boot/attach-time kernel panic (DoS) in case 1-2; a UAF *read* of a
484-byte driver-allocated struct in case 3 (no attacker-controlled content
is written through it before free — values are copied into intel_dsi fields
and programmed to display registers; worst case is garbage register
programming after the freed block is reallocated, still no write primitive
from userland). No privilege escalation path: the trigger is not
user-reachable.

## Fix

`fix.diff`: (a) bail to the (correct, pre-connector) `err` label when
`vbt.dsi.config` is NULL in vlv_dsi_init; (b) NULL the pointer after the
pps-failure kfree in intel_bios.c so no dangling pointer survives. Both
hunks are required; neither alone closes case 3.

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