# DF-4145 — `ucNumDPMLevels==0` pplib state leaves `num_levels==0`: the `:1619` `levels[num_levels-1]` store is a **WILD byte-zero write at `ps + 0xBFFFFFFFF`** (mechanism corrected by the rig), plus a same-offset OOB read

- File: `sys/dev/drm/radeon/trinity_dpm.c`
- Class: kernel out-of-bounds write (CWE-787) / OOB read (CWE-125)
- **Verified via the verbatim-code rig** (`rig/`, 68 blocks byte-identical to
  the guest's `/usr/src/sys`).
- **IMPORTANT mechanism correction** (rig-proven, see VERDICT.md): the
  finding claims the write lands at `ps-1`, the MSB of
  `pi->requested_rps.ps_priv`. That is **arithmetically impossible**: `ps->num_levels`
  is `u32`, so `ps->num_levels - 1` is `0xFFFFFFFF`, and the array subscript
  scales by `sizeof(struct trinity_pl) == 12` (verbatim layout mode), putting
  the store at **`ps + 4 + 0xFFFFFFFF*12 + 7 = ps + 0xBFFFFFFFF`** — a wild
  1-byte-zero store ~48 GiB past the object (gdb computes exactly the
  observed fault address: `0x140047b1af == ps + 0xBFFFFFFFF`). The trigger,
  the executing line and the OOB-write class of the finding are confirmed;
  the precise target and the "non-canonical ps_priv" consequence are
  corrected. `trinity_dpm_get_sclk` reads `levels[num_levels-1].sclk` at the
  same wild offset (`ps + 0xBFFFFFFF8`) — an OOB read feeding the watermark
  path, not an intra-object garbage read.

## What the rig demonstrates (baseline build = production code)

| mode | result |
|---|---|
| `4145-guard` | verbatim `trinity_apply_state_adjust_rules` on a `num_levels==0` state → the `:1619` store faults at exactly `ps + 0xBFFFFFFFF` (unmapped) — `RESULT: FAULT addr=0x14004b4fff` where `ps=0x8004be000` |
| `4145-fullflow` | full production flow (init on the crafted image, state selection, verbatim `trinity_dpm_pre_set_power_state`): the `:1603-:1618` block provably executes (`Dpm0PgNbPsLo` 1→2, `DpmXNbPsLo` 2→2), then the `:1619` store lands in a canary page mapped at exactly `ps+0xBFFFFFFFF`: **exactly 1 byte of 12288 changed — the byte at the computed wild offset written to 0x00**; `trinity_dpm_get_sclk` then reads the same wild region (returns the canary bytes) |

## Fixed build (this finding's `fix.diff`, A/B on the identical image)

The parser rejects states with zero usable DPM levels (`k == 0` after the
idx loop) with a full unwind, and `apply_state_adjust_rules` guards the
write with `if (ps->num_levels > 0)`. Fixed run: `4145-fullflow` init
returns `-EINVAL` (state never parsed), `4145-guard` never reaches the
write — no fault; `good` table unchanged.

## Build / Run (on the DragonFly guest)

```
cd rig && sh ./build.sh /usr/src DF-4145
cd rig && sh ./run.sh
```

## Verdict

Reproduced with corrected mechanism (verbatim-rig): the trigger and the
OOB store at `trinity_dpm.c:1619` are real and attacker-controlled in
reachability; the write is a wild constant-zero byte at object+~48 GiB — in
kernel context an unmapped-address page fault (panic) or, where kernel VA
happens to be mapped there, a 1-byte zeroing of unrelated memory. The
finding's `ps-1`/pointer-MSB surgical-write claim is refuted by C unsigned
arithmetic and rig observation. See `VERDICT.md`, `verdict.json`.
