# DF-3610 — NULL-pointer dereference in si_dpm_enable when the VBIOS power table has no ATOM_PPLIB_CLASSIFICATION_BOOT state (boot_ps unvalidated)

**Severity:** Medium  **Confidence:** certain  **Status:** reproduced (harness)
**Impact:** panic

## What

rdev->pm.dpm.boot_ps is set ONLY in si_parse_pplib_non_clock_info() (si_dpm.c:6726-6727) when a VBIOS power state carries ATOM_PPLIB_CLASSIFICATION_BOOT. A crafted VBIOS with no such state (or ucNumEntries==0, which also yields a ZERO_SIZE_PTR dpm.ps that passes the !ps check at :6842) leaves boot_ps==NULL while si_parse_power_table returns 0. radeon_pm.c:1448 IGNORES the dpm.init return, :1449 assigns current_ps=requested_ps=boot_ps, and radeon_dpm_enable -> si_dpm_enable dereferences it: first fault at si_populate_smc_initial_state:4372 via ni_get_ps(NULL)->ps_priv (offset 0x28). Harness executes the exact chain in a forked child: SIGSEGV at 0x28 == kernel NULL-deref panic during DPM enable (boot-time DoS with malicious VBIOS). No live GPU trigger possible on the virtio-only audit guest; module radeon.ko present.

## Reproduce

```
sh build.sh   # cc -O2 -Wall -o harness harness.c
sh run.sh     # prints [A] buggy-path behaviour, [B] fixed-path behaviour
```

Expected decisive output (see run.log): the `[A]` section shows the fault or
corruption the kernel would take; the `[B]` section shows the behaviour with
fix.diff applied.

No AMD GPU is attached to the audit QEMU guest (virtio-only), so the radeon
DPM path cannot be exercised live; the harness replicates the exact kernel
expressions with crafted-VBIOS inputs (house methodology, cf. DF-1137..1140).

## Fix

`fix.diff` — validated: `git apply --check` clean; `make si_dpm.o` in
sys/dev/drm/radeon with KERNBUILDDIR=/usr/obj/usr/src/sys/X86_64_GENERIC
compiles -Werror clean with all five pass-2 fixes stacked; harness `[B]`
shows the primitive gone.
