# DF-4205 — vlv_dsi_init dereferences vbt.dsi.config without NULL/dangling guard

File: `sys/dev/drm/i915/vlv_dsi.c` (pass 2)
Severity: Low | Confidence: certain | CWE-476 (NULL pointer dereference) / CWE-457 (use of uninitialized/freed pointer variant)

## Build / Run

No build or run: Phase V skipped per contract (Low severity, firmware-gated
trigger). The audit QEMU guest has no Intel GPU, so i915 never attaches and
`vlv_dsi_init` is not reachable there; the trigger additionally requires a
VBT whose child-device list declares a MIPI output while the
`BDB_MIPI_CONFIG` block is absent (or an OOM at a specific kmemdup).

Static repro of the path is fully cited below — the defect is provable from
source alone.

## Expected behavior if triggered (on real VLV/CHV/BXT hardware)

* Missing `BDB_MIPI_CONFIG` + MIPI child device present:
  kernel NULL-page deref panic at driver attach (`config->dual_link`,
  vlv_dsi.c:1797).
* OOM in the `pps` kmemdup after `config` kmemdup succeeded:
  1-byte UAF read at vlv_dsi.c:1797, then full parse of freed memory in
  `intel_dsi_vbt_init` (intel_dsi_vbt.c:523-544) and `->pwm_blc` read at
  vlv_dsi.c:1826.

## The path (path:line)

1. `vlv_dsi_init()` vlv_dsi.c:1747 — `intel_bios_is_dsi_present(dev_priv, &port)`
   returns **true** based on the *child device list*
   (intel_bios.c:2034-2047: any child with `DEVICE_TYPE_MIPI_OUTPUT` and
   `dvo_port` in {DVO_PORT_MIPIA, DVO_PORT_MIPIC}).
2. `dev_priv->vbt.dsi.config` is populated by a **different** BDB section:
   `parse_mipi_config()` intel_bios.c:826-830 — if `find_section(bdb,
   BDB_MIPI_CONFIG)` fails it returns with `dsi.config == NULL`.
3. intel_bios.c:843-851 — `dsi.config = kmemdup(...)`; on `pps` kmemdup
   failure (line 848-851) it does `kfree(dev_priv->vbt.dsi.config)` **without
   setting it to NULL** → dangling.
4. Back in vlv_dsi_init: vlv_dsi.c:1797 `dev_priv->vbt.dsi.config->dual_link`
   and vlv_dsi.c:1826 `dev_priv->vbt.dsi.config->pwm_blc` — dereferenced
   with **no guard**.

Nothing between intel_bios_init and vlv_dsi_init re-checks `dsi.config` or
`dsi.panel_id` (which stays `MIPI_DSI_UNDEFINED_PANEL_ID` when the section is
missing — intel_bios.c:816,855).

## Distinct from known findings

* DF-1390: OOB *indexing* inside `parse_mipi_config` (`config[panel_type]`).
* DF-1773: NULL-deref of `vbt.lfp_lvds_vbt_mode` in `intel_dsi_vbt_init`
  (different pointer, later in the call chain — it never runs because
  vlv_dsi.c:1797 faults first).
* DF-4122: block-size floors in other parse_* consumers.

## Fix

Guard at the consumer (this file) + NULL the dangling pointer at the
producer — see `fix.diff`.

## Threat model / impact ceiling

Attacker needs to control the Intel VBT (BIOS/OpROM flash = root) or hit a
narrow OOM. Impact: kernel panic at driver attach (local DoS of the boot /
driver load), not arbitrary code execution. Rooted-firmware supply chain or
broken BIOS is the realistic scenario.
