# DF-1437 — Heap OOB write in `sumo_construct_vid_mapping_table` via unchecked `usVoltageIndex`

## Verdict: REPRODUCED (source-level + harness) — latent radeon-DRM bug, heap OOB write

## The bug

`sys/dev/drm/radeon/sumo_dpm.c`, function `sumo_construct_vid_mapping_table`,
lines 1616-1629:

```c
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
    if (table[i].ulSupportedSCLK != 0) {
        vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
            table[i].usVoltageID;                                   /* :1624 OOB */
        vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
            table[i].usVoltageIndex;                                /* :1626 OOB */
    }
}
```

`usVoltageIndex` is a `u16` (0..65535) from the VBIOS `sAvail_SCLK` list
(`ATOM_AVAILABLE_SCLK_LIST`). `entries[]` is fixed at
`SUMO_MAX_NUMBER_VOLTAGES` (4) (`sumo_dpm.h:52,66`). **No check** that
`usVoltageIndex < 4`. With `usVoltageIndex = 0xFFFF` the write lands at byte
offset `65535 * 8 = 524280` past `entries[0]` (~512 KB), corrupting a huge
slab region. The function is also called from `trinity_dpm.c` and
`kv_dpm.c` (3 APU DPM drivers affected).

## Harness proof

```
VBIOS usVoltageIndex             = 7 (u16, no bound check)
SUMO_MAX_NUMBER_VOLTAGES         = 4 (sumo_dpm.h:52)
(Worst case usVoltageIndex=0xFFFF -> write at offset 131070 bytes)
entries[4] = {vid_7bit=0x00 vid_2bit=0x00}  <-- FIRST OOB WRITE
entries[7] = {vid_7bit=0x15 vid_2bit=0x07}  <-- OOB (target)
RESULT: heap OOB write CONFIRMED at sumo_dpm.c:1624
```

## Fix

`fix.diff` adds `if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES)
continue;` at the top of the loop body, before the unchecked index use.

## Module build validation (Phase 8)

Both radeon fixes (DF-1209 in `r100.c`, DF-1437 in `sumo_dpm.c`) applied;
`radeon.ko` built under `-Werror`: `sumo_dpm.o` (20056 bytes) and `r100.o`
(64504 bytes) produced, 0 errors, `radeon.ko` (2029128 bytes) linked.
