# DF-3689 — verdict narrative

## Finding

Source-certain heap OOB read; runtime-inconclusive on this guest (no AMD GPU). smu7_patch_voltage_dependency_tables_with_lookup_table uses each dependency record's vddInd/vddcInd - a raw u8 (0..255) from the VBIOS ATOM tables (process_pptables_v1_0.c:398 ucVddcInd etc.) - to index vddc/vddgfx_lookup_table->entries[] with no range check (:1860-1862, :1866-1868, :1873-1875, :1879-1881); smu7_patch_voltage_workaround does the same at :2135. The lookup tables are kmalloc'd for max_levels=16 records (process_pptables_v1_0.c:286-287/:295-296) while their count field is the VBIOS ucNumEntries, so indices above both 16 and count read adjacent kernel heap. The garbage value read is stored into the dependency record's vddc and later programs real voltages (hardware-safety impact) and feeds smu7_calc_voltage_dependency_tables; no direct userspace disclosure was found (sysfs pp_table dumps the raw atom table, not the patched records). DF-1168 covers the ucMemoryClockIndex/ucEngineClockIndex sinks; this is the distinct vddInd sink family. Harness: 239/255 crafted dep entries read past the 16-record allocation, max offset 2550 bytes past entries[0].

## Root cause (kernel references)

- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1860`
- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1866`
- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1873`
- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1879`
- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:2135`
- `sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:286`

## What was verified, and how

1. **Source-level certainty.** Full-file pass-2 audit of smu7_hwmgr.c (5147 lines) with
   the parse-side preconditions traced into processpptables.c / process_pptables_v1_0.c
   (VBIOS u8 counts unvalidated; offset==0 subtables parse-legal NULL) and the struct
   geometry verified in ppatomctrl.h / smu7_hwmgr.h / hardwaremanager.h /
   dm_pp_interface.h.
2. **Harness on the guest** (DragonFly 6.5-DEVELOPMENT x86_64, `cc` base toolchain):
   `vddind_oob_read.c` reproduces the exact kernel code shape and/or arithmetic with 1:1 struct
   layouts. Output in `run.log`.
   Compiled with `-O0` — at `-O2` the compiler detects the array-index UB and
   misoptimizes the accounting loops (itself a hint of what the kernel code does).
3. **Hardware absence.** The guest is virtio-only: no AMD GPU on PCI, amdgpu not
   loaded. The in-kernel trigger requires an SMU7 ASIC (CI/Topaz/Tonga/Fiji/Polaris/
   Vegam) with a crafted VBIOS, VFIO passthrough of a malicious card, or a root
   sysfs pp_table write. Per pass-2 spawn instructions this is recorded as
   **inconclusive** (matching DF-3585/DF-3619/DF-3644 precedent for the same class),
   impact none *on this guest*.

## Fix validation

fix.diff authored post-verification against the read-only sys/ tree. Not built: a
kernel rebuild with drm cannot be exercised on a GPU-less guest, so fix validation is
`not_testable`; the diffs are minimal, local, and mechanically checkable against the
cited lines.

## 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.
