# DF-3586 Verification Verdict

**Severity:** Medium — crafted-VBIOS NULL-deref panic (CWE-476)
**Verification method:** source-line proof. Kernel-level execution impossible on
the verification guest (no AMD GPU); the defect is a direct NULL dereference
whose reachability is fully determined by source — no harness adds information.

## Source proof chain

1. `boot_ps` assignment is conditional on a BIOS-controlled classification bit:
   `sys/dev/drm/amd/amdgpu/si_dpm.c:7123-7124`
   `if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) adev->pm.dpm.boot_ps = rps;`
   No other assignment exists; adev is zero-initialized => stays NULL otherwise.

2. `si_parse_power_table()` has no "needs a BOOT state" validation
   (si_dpm.c:7210-7300) and returns 0; `si_dpm_init` returns 0 (si_dpm.c:7343-7345);
   `si_dpm_sw_init` succeeds and even propagates the NULL
   (`si_dpm.c:7720`: `adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;`).

3. `si_dpm_hw_init` (si_dpm.c:7748-7766) -> `si_dpm_enable` (si_dpm.c:6778):
   `struct amdgpu_ps *boot_ps = adev->pm.dpm.boot_ps;` (`:6783`) — no NULL check —
   passed at `:6846` and `:6867`, and `si_init_smc_table` (`:6830`) internally calls
   `si_populate_smc_initial_state(adev, adev->pm.dpm.boot_ps, table)`
   (si_dpm.c:5159, 5205).

4. Crash sink: `si_populate_smc_initial_state` (si_dpm.c:4829-4834):
   `struct si_ps *initial_state = si_get_ps(amdgpu_initial_state);`
   `si_get_ps` (si_dpm.c:1971-1976) does `aps->ps_priv` on the NULL pointer
   => kernel read from page 0 (fixed low address) => fatal page fault.
   Additional unguarded sinks: si_dpm.c:6118 (`boot_state->performance_levels[0]`)
   via `si_populate_mc_reg_table(adev, boot_ps)` at :6846, and
   `si_dpm_disable`'s `ni_update_current_ps(adev, boot_ps)` at :6932.

5. Trigger surface: boot / `kldload amdgpu` / resume with an SI GPU whose VBIOS
   PowerPlayInfo state array contains no BOOT-classified entry. Purely
   VBIOS-content-controlled; no privilege required beyond having the hardware
   present. Impact: panic (driver init / system boot DoS), no memory-control
   primitive (fixed-address read).

## Why `inconclusive` and not kernel-reproduced

Verification guest is virtio-only: `pciconf -l` shows zero vendor-0x1002
devices; `amdgpu.ko` loads (`[drm] amdgpu kernel modesetting enabled`) but no
SI asic attaches, so `si_dpm_enable` never runs. The NULL-deref itself is
arithmetically trivial (`NULL->ps_priv`) — source-certain.

## Fix validation

`fix.diff` adds an early `if (boot_ps == NULL) return -EINVAL;` in
`si_dpm_enable` (covers hw_init and resume paths; dpm then degrades to disabled
via the existing `adev->pm.dpm_enabled = false` handling, si_dpm.c:7760-7763).
Patch git-apply-verified against the read-only tree; logic-level validation only
(no kernel build this run — guard introduces no type changes).

## Verdict

**inconclusive** at kernel level (no SI hardware on guest); source-certain
NULL-deref defect; one-line guard recommended as in `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.
