CENTRAL FIX: V1 PowerPlay parser has no bounds-validation layer β every firmware USHORT offset/UCHAR count/UCHAR index is consumed unvalidated (V1 side of DF-4247; count-provenance root of the powerplay count family)
Summary
The V1 parser serves all SMU7 ASICs (Tonga/Fiji/Polaris10/11/12/VegaM) consuming every firmware offset/count/index with zero validation against soft_pp_table_size and zero clamping to destination capacities - the parse-time root behind DF-1166(V1), 4001/4002/4004, 4036/4038a/4041b, and home of knowns DF-1574..1577. CENTRAL FIX (415+/83-, git-apply OK, kernel-toolchain syntax-validated, 11/11 clamp/range unit tests on the guest): the DF-4247 range-ok/clamp layer extended to every V1 deref site - all 16 USHORT offsets range-checked (Tonga-vs-Fiji struct dispatch), counts clamped to image AND destination constants (SCLK 8/MCLK 4/MM 8/lookup 16/VCE 6), VCE indices clamped (killing the entries[-1] underflow), NULL guards + off-by-one fix. NEUTRALIZATION TABLE: combined DF-4247+DF-4388 neutralizes DF-1574/1575/1576(V1)/1577/4389 + DF-1166(V1)/4001/4002/4004/4036/4038a/4041b; per-file fixes still stand for the V0-parser ASICs (smu8/iceland/topaz), the smumgr-local voltage tables, the entries[count] off-by-ones, and the NULL-deref consumers.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4388 Β· 30 filesDF-4388 β V1 PowerPlay parser has no central bounds-validation layer (central fix for the powerplay count family, V1 side of DF-4247)
Status: REPRODUCED (verbatim-rig evidence class, DF-4165/4247/4396). Fix
A/B-validated in the same rig: fixed. See VERDICT.md for the full story.
sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c parses the
Tonga-format VBIOS PowerPlay table for Tonga, Fiji, Polaris10/11/12,
VegaM (hwmgr.c:86 default PP_TABLE_V1; smu7_hwmgr.c:5144 binds
pptable_v1_0_funcs). Every firmware USHORT sub-table offset, UCHAR entry
count and UCHAR index is consumed with zero validation against
hwmgr->soft_pp_table_size and (for counts) zero clamping to destination
array capacities.
How it was verified (no AMD GPU needed β proven absent, hw_probe.log)
The entire production parser (process_pptables_v1_0.c:34-1337 β every
helper, every parse function, the exported entry getters, the
pptable_v1_0_funcs vtable) was compiled into a guest-side harness:
rig/gen_rig.shmachine-extracts the parser slice plus 24 header slices (pptable_v1_0.h firmware structs, hwmgr/hwmgr_ppt/hardwaremanager/ power_state/kgd/atombios type blocks, the PP_ASSERT_WITH_CODE and GET_FLEXIBLE_ARRAY_MEMBER_ADDR macros).rig/check_verbatim.shre-verified all 24 blocks byte-identical on the guest against/usr/src/sysβ the tree its running kernel was compiled from (build.log:ALL VERBATIM CHECKS PASSED; guestβhost MD5s of all ten sliced sources inenv.txt).- The fixed build is the same slice + exactly this pack's
fix.diff(applied to a copy of the pristine full file withpatch --fuzz=0; proven bidirectionally: forward apply succeeds, reverse apply restores the pristine file byte-exactly). - Shims (
rig/rig_shims.h) touch no defect path: identityle16_to_cpu/le32_to_cpu, guard-backed end-anchoredkzalloc(the first byte past any allocation is a PROT_NONE page β this is what turns the decisive destination heap OOB WRITE into a fault at a computable offset), a minimizedstruct pp_hwmgrwith production names/types for every field the parser and the fix consult. - Crafted tables mimic real Tonga-format PowerPlay tables; the image ends at a guard page (OOB source reads fault at a computable offset), or at a patterned victim region (leak mode), or starts after a PROT_NONE page (negative-index underflow mode).
Observed (run.log; identical in run.2.log / run.3.log, md5-equal)
Baseline β 13 SIGSEGVs + 1 byte-exact leak + 2 behavioral proofs, every one at the exact predicted verbatim site:
| mode | observation | verbatim site |
|---|---|---|
| vddc-lookup-255-write | DEST heap OOB WRITE: first OOB byte at kzalloc(164)+0; loop bound ucNumEntries=255 vs 16-record allocation; source records all in-image | get_vddc_lookup_table :176-190 |
| statearray-offset-oob | source OOB read at image+65281 (0xFF00) | :1042-1053 |
| thermal-offset-oob | image+65281 | :891-897 |
| fan-offset-oob | image+65280 | :922-929 |
| sclkdep-offset-oob | image+65280 | :781-783,420 |
| ppm-offset-oob | image+65281 | :301-305,214-215 |
| vce-offset-oob | image+65281 | :1219-1222 |
| sclk-count-255 | image+131 (first byte past a 131B image) | :438-451 |
| leak-canary | 175/175 field values byte-exact with victim bytes past the image (mm count=40 vs 5 records) | :710-724 |
| vce-sclk-index-255 | image+2914 (entries[0xFF] = sclk_table+2+255*11) |
:1249-1252,1261 |
| vce-mclk-underflow | imageβ2 (entries[ucNumEntries-1] = entries[-1] with count 0) |
:1263-1267 |
| entry-offbyone | image+178 (<= guard accepts entry_index==ucNumEntries) |
:1310-1321 |
| pcie-null-vdddepsclk | NULL DEREF at NULL+0 (vdd_dep_on_sclk->count, sclk offset 0) |
:522 |
| gpio-null-vdddepsclk | NULL DEREF at NULL+0 | :745 |
| gpio-gate-zero-offset | GPIO "parsed" from the PowerPlay header itself when usGPIOTableOffset==0 (gate tests the never-NULL pointer) | :790-792,843-845 |
| vce-count-unclamped | hwmgr->num_vce_state_tables stored = 200 (array holds 6) |
:1328 |
Regression control (clean-valid): a fully valid table parses identically in both builds (all counts, limits, fan params, 2 states, 2 VCE states, rc=0) β the fix changes nothing on valid firmware.
Fixed build, identical inputs: 0 SIGSEGVs. Lookup count clamped 255β16,
dep counts clamped to the records that fit (255β3, 40β5), oversized offsets
rejected (rc=-1/-22), VCE indices clamped to 0, entries[-1] gone, entry
< guard rejects one-past (rc=-1), NULL guards on PCIE/GPIO (rc=-22),
GPIO gate moved to the offset (skipped), VCE count clamped 200β6.
Build / run / verify (on the audit guest)
cd findings/poc/DF-4388 ./build.sh /usr/src # verbatim check vs /usr/src + rig_base + rig_fixed ./run.sh # baseline (verbatim) vs fixed A/B over 18 modes
Layout mode prints the exact verbatim struct geometry (PP table 77B, Tonga
state 20B, SCLK rec 11B, MM rec 23B, lookup rec 8B β get_vddc_lookup_table
allocates 4+10*16=164 bytes for up to 255 firmware entries).
Historical artifacts from the pre-verification run (compile-validation and
clamp unit test): syntax_check_guest.txt, unit_test_guest.log,
fix_build.log, fix_run.log, v1_clamp_test.c,
process_pptables_v1_0_fixed.c (byte-equal to pristine+fix.diff, proven in
build.log).
DF-4388 VERDICT (verify run, 2026-10-14)
Status: REPRODUCED (verbatim-rig evidence class). Every defect family the
finding enumerates was demonstrated in byte-identical production code β
including the heap out-of-bounds WRITE at get_vddc_lookup_table() β and
the pack's fix.diff was A/B-validated in the same rig: fixed. In-kernel
execution is AMD-ASIC-gated on this guest (no AMD GPU β proven,
env.txt / hw_probe.log).
1. Method
The guest cannot attach amdgpu (no 1002: PCI device, no /dev/dri).
Following the DF-4165/4247/4396 evidence class for crafted-firmware
parsers, the actual production parser was compiled into a guest-side
harness:
rig/gen_rig.shextracts process_pptables_v1_0.c:34-1337 β the entire parser body (every static helper,pp_tables_v1_0_initialize/uninitialize, the exportedget_number_of_powerplay_table_entries_v1_0/get_powerplay_table_entry_v1_0, thepptable_v1_0_funcsvtable) plus 24 header slices: pptable_v1_0.h 24-30 + 33-436 (every ATOM_Tonga_ firmware struct, packed layout preserved β sliced around its single#include "hwmgr.h"at :32), hwmgr_ppt.h 31-113 (phm_ppt_v1_ dest types), hwmgr.h 88-186/335-345/375-409/454-465/485-493/497-524/595-624/ 626-631/633-677/679-685, hardwaremanager.h caps enum + helpers + PP_Clocks + platform descriptor, power_state.h 26-187, kgd_pp_interface amd_vce_state + AMD_MAX_VCE_LEVELS, atombios.h ATOM_COMMON_TABLE_HEADER, atom-types.h, and the verbatim PP_ASSERT_WITH_CODE / GET_FLEXIBLE_ARRAY_MEMBER_ADDR macros from pp_debug.h.rig/check_verbatim.shre-verified all 24 blocks byte-identical β run on the guest against/usr/src/sys, the tree its running kernel was compiled from (build.log:ALL VERBATIM CHECKS PASSED; guestβhost MD5 equality of all ten sliced sources,env.txt).- The fixed build is the same slice + exactly this pack's fix.diff
(applied to a copy of the pristine full file with
patch --fuzz=0; proven bidirectionally: forward apply succeeds with no rejects, reverse apply restores the pristine file byte-exactly; the packed referenceprocess_pptables_v1_0_fixed.cis byte-equal to pristine+fix.diff). - Harness shims (
rig/rig_shims.h) touch no defect path: identityle16_to_cpu/le32_to_cpu(LE host, like the target), a minimizedstruct pp_hwmgrcarrying production names/types for every field the parser and the fix consult (soft_pp_table,soft_pp_table_sizeas hwmgr.h:718-719;vce_states[AMD_MAX_VCE_LEVELS],num_vce_state_tablesas hwmgr.h:722-723), andkzalloc/kfreemapped end-anchored at a PROT_NONE guard page so the first byte past any allocation faults β the destination-OOB-write detector. The allocator fidelity tradeoff (kmalloc slab vs mmap) touches no defect path: the defect is the count-vs-allocation mismatch (255 firmware entries vs a 16-record allocation), not the allocator.
Crafted tables mimic real Tonga-format PowerPlay tables (revision 7 = ATOM_Tonga_TABLE_REVISION_TONGA, verbatim packed structs, little-endian host so struct member writes produce exactly the firmware bytes). Images end exactly at a PROT_NONE guard page (source OOB reads fault at a computable offset), at a patterned victim region (leak mode, no fault so the captured bytes can be compared), or start right after a PROT_NONE page (negative-index underflow mode).
2. Observed (run.log; byte-identical in run.2.log / run.3.log, md5-equal)
Exact layouts from the verbatim structs (layout mode): POWERPLAYTABLE=77B,
Tonga state=20B, SCLK rec=11B (Polaris 15B), MCLK rec=13B, MM rec=23B,
lookup rec=8B β get_vddc_lookup_table allocates 4+1016=164B* while
its copy loop is bounded by firmware ucNumEntries (β€255).
Baseline β production code faults on every crafted input (13 SIGSEGVs), each classified by the fault handler, plus the leak leg and two behavioral proofs:
| mode | fault offset vs table | verbatim site |
|---|---|---|
| vddc-lookup-255-write | kzalloc(164)+0 β DESTINATION HEAP OUT-OF-BOUNDS WRITE (source records all in-image; write loop bound 255 vs 16-record allocation; up to ~2390B of firmware-chosen usVdd/usCAC* values past the object) |
get_vddc_lookup_table :176-190 |
| statearray-offset-oob | 65281 vs 256 | state_arrays->ucNumEntries at base+0xFF00 β :1042-1053 |
| thermal-offset-oob | 65281 vs 256 | thermal_controller->ucType β :891-897 |
| fan-offset-oob | 65280 vs 256 | fan_table->ucRevId β :922-929 |
| sclkdep-offset-oob | 65280 vs 256 | sclk_dep_table->ucRevId β :781-783 β :420 |
| ppm-offset-oob | 65281 vs 256 | atom_ppm_table->ucPpmDesign β :301-305 β :214-215 |
| vce-offset-oob | 65281 vs 256 | vce_state_table->ucNumEntries β :1219-1222 |
| sclk-count-255 | 131 vs 131 | entries[3] read past a 3-record table β :438-451 |
| vce-sclk-index-255 | 2914 vs 256 | entries[ucSCLKIndex=0xFF].ulSclk at sclk_table+2+255*11 β :1249-1252,1261 |
| vce-mclk-underflow | imageβ2 | entries[ucNumEntriesβ1] = entries[-1] with count 0 β :1263-1267 |
| entry-offbyone | 178 vs 170 | entry_index <= ucNumEntries accepts one-past; state_entry->usClassification at image end +10 β :1310-1321 |
| pcie-null-vdddepsclk | NULL+0 | vdd_dep_on_sclk->count with sclk offset 0 β :522 (DF-1575) |
| gpio-null-vdddepsclk | NULL+0 | same in get_gpio_table β :745 (DF-1575) |
Leak leg (leak-canary): MM dep ucNumEntries=40 with only 5 records in
image, image followed by patterned victim bytes: the parse completes and
175/175 field values (dclk+vclk+eclk+aclk+samclock of entries[5..39])
are byte-exact with the victim bytes at the exact OOB source positions β
kernel-heap data past soft_pp_table flows 1:1 into
pp_table_information->mm_dep_table, which userland reads back through
the powerplay sysfs/DPM interfaces. Stable across 3 runs.
Behavioral proofs: gpio-gate-zero-offset β with
usGPIOTableOffset==0 the :843 gate tests powerplay_table+0 (never
NULL), so get_gpio_table runs and reads ucVRHotTriggeredSclkDpmIndex
from PowerPlay header byte 1 (the "SCLK DPM index for VRHot cannot exceed"
assert fires on header bytes); vce-count-unclamped β
hwmgr->num_vce_state_tables stored = 200 against a 6-entry
vce_states[] (the fill loop is gated, but every consumer walking the
stored count reads past the array β DF-4389's root, :1328).
Regression control (clean-valid): a fully valid table (2 states, fan, thermal, MM 2, PowerTune, SCLK 3, MCLK 2, PCIE 1, hard limits, VCE 2 states, PPM, vddc lookup 4, vddgfx lookup 2, GPIO) parses identically in both builds β rc=0, all counts and limits byte-equal, TDP=250, vce_states[0]={evclk=100000, sclk=30000}.
3. Fix validation (A/B, identical crafted inputs)
rig_fixed = same verbatim slice + this pack's fix.diff (checker-proven
identity, bidirectional patch proof). All 13 fault modes: no fault β
oversized offsets rejected (rc=-1/-22), counts clamped to the entries that
fit AND to destination constants (255β16 lookup, 255β3 sclk, 40β5 mm),
VCE indices clamped to 0, entries[-1] gone, one-past entry rejected
(rc=-1), NULL guards on PCIE/GPIO (rc=-22); leak-canary: 0 out-of-image
values; gpio-gate: GPIO parse skipped when the offset is 0; vce count
stored clamped to 6. clean-valid: identical behavior to baseline.
Baseline corrupts, patched slice is clean on the same input β fix
validated (fix_validation = the FIXED half of run.log; three
identical runs). A rebuilt-kernel validation was not performed: the fix
sites execute in-kernel only on AMD ASICs absent from this guest; per the
verbatim-rig protocol (DF-4165/4247/4396) the fixed slice was A/B-validated
in the same rig. fix.diff is authored against the pristine read-only
sys/ tree and was never applied there (guest /usr/src verified pristine
by MD5 before and after).
4. Primitive and impact
Primitives, all in verbatim production code:
- Heap OOB WRITE (
get_vddc_lookup_table:176-190): a firmware UCHAR (ucNumEntriesβ€ 255) bounds a copy loop into a fixed 164-byte allocation β up to ~2390 bytes past the object with firmware-chosen content (usVdd,usCACLow/Mid/Highβ 16-bit values), via bothusVddcLookupTableOffsetandusVddgfxLookupTableOffset. In-kernel this is kmalloc-heap corruption; the realistic floor is a kernel panic/oops (impact recorded asdos), with content-controlled heap overwrite potential. - Attacker-directed source OOB reads out of the kernel-heap PowerPlay
image: USHORT offsets reach +65535, UCHAR count loops read linearly
past the image (fully value- and length-controlled), UCHAR indices Γ
record sizes reach +2807 (VCE sclk index),
entries[-1]underflow reads before the image β with the leaked bytes converted 1:1 into parsed DPM tables exposed to userland (175/175 byte-exact, proven). - NULL-deref kernel panics (
vdd_dep_on_sclkinget_pcie_table/get_gpio_table) whenever the ROM omits the SCLK dependency table but ships a PCIE or GPIO table; plus the never-NULL gate defect that reads the PowerPlay header as a GPIO table when the offset is 0. - Unclamped count store (
num_vce_state_tablesβ€ 255 vsvce_states[6]) β DF-4389's provenance root.
Threat model (the family's established one): crafted/corrupted GPU VBIOS
(flashed ROM, vfio-pci romfile override, malicious discrete device) parsed
at driver attach (pptable_v1_0_initialize), or root re-parsing a crafted
blob through /sys/class/drm/card0/device/pp_table β pp_dpm_set_pp_table
β amd_powerplay_reset β pptable_init. No unprivileged userland trigger
on stock hardware β same class as DF-4247 (V0 twin). Demonstrated
out-of-kernel context (rig); the write primitive's in-kernel consequence
(panic at minimum) follows from the verbatim instruction stream and the
production allocation sizes.
5. Honest limitations
- Demonstrated with production instructions and production struct layouts, but in a userland mapping, not the kernel's kmalloc heap. The kzalloc shim's guard pages detect the destination overflow; they do not model slab freelist interaction (whether the ~2390-byte overwrite is weaponizable in-kernel was not investigated β the VBIOS-gated threat model gives the attacker kernel-equivalent control already at ROM-flash time in the realistic scenarios).
- The leak leg proves source bytes are captured into parsed tables; the slab neighborhood contents in kernel context are the allocator's, not a controlled victim.
entry-offbyonerequires a caller passingentry_index == ucNumEntries(the stock caller loops 0..N-1), so it is a latent wrong-guard defect (defense-in-depth), demonstrated by direct call.- The crafted images are synthetic minimal tables; a real crafted ROM must also satisfy earlier ATOM ROM parsing stages, which precede and do not constrain these fields.
- Offset modes demonstrate 6 of the 16 USHORT consumers concretely; the
remaining ten (MM/PowerTune/MCLK/HardLimit/PCIE/VddcLookup/VddgfxLookup/
GPIO/Fan/VCE-in-entry-getter) are the same unvalidated
powerplay_table + offsetpattern at :772-792/:281-304/:1219-1240 and are all covered by the fix's range checks (validated where exercised: MM count clamp in leak-canary, vddc/vddgfx lookup range checks and count clamps in the write mode, VCE table checks in the index modes).
6. Bottom line
The central-fix claim is verified end to end: the V1 parser consumes every firmware offset/count/index unvalidated (heap OOB write, OOB reads with byte-exact leak, NULL derefs, negative-index underflow, off-by-one, unclamped count store β 16 defect modes demonstrated in byte-identical production code), and the pack's fix.diff neutralizes every demonstrated mode on identical input while leaving valid-table parsing byte-identical.
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.
Fix verification
fixedA/B-validated in the verbatim rig (DF-4165/4247/4396 protocol): rig_fixed = same byte-identical slice + fix.diff (patch --fuzz=0, reverse-apply restores pristine byte-exactly; byte-equal to the packed process_pptables_v1_0_fixed.c). On the identical crafted inputs that fault the baseline 13 times, the fixed build faults ZERO times: vddc lookup count clamped 255->16 (write gone), oversized USHORT offsets rejected (rc=-1/-22), dep counts clamped to image and destination constants (255->3 sclk, 40->5 mm), VCE indices clamped, entries[-1] underflow eliminated, entry_index guard corrected to '<', vdd_dep_on_sclk NULL guards added (rc=-22), GPIO gate moved to the offset, num_vce_state_tables clamped 200->6; clean-valid table parses byte-identically to the baseline build. A rebuilt-kernel A/B was not performed: the fix sites execute in-kernel only on AMD ASICs absent from this guest.
run.log FIXED half (0 SIGSEGV / 11 graceful rejections + clamped counts); build.log (verbatim checks + bidirectional fix proof); fix.diff
Confirmed kernel references
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:176
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:1042
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:522
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:745
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:1263
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:1310
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:1328
- sys/dev/drm/amd/powerplay/hwmgr/hwmgr.c:86
- sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:5144
Detail
Exploit chain
crafted/corrupted GPU VBIOS PowerPlay table (Tonga format, PP_TABLE_V1: Tonga/Fiji/Polaris10/11/12/VegaM) at driver attach -> pptable_v1_0_initialize -> get_vddc_lookup_table heap OOB write (255 firmware entries into a 16-record kmalloc(164), ~2390B content-controlled overwrite) and/or OOB reads with byte-exact leak into userland-readable DPM tables and/or vdd_dep_on_sclk NULL-deref panic; alternatively root-written /sys/class/drm/card0/device/pp_table -> pp_dpm_set_pp_table -> amd_powerplay_reset -> same parse. No unprivileged userland route on stock hardware.
Evidence (decisive lines)
run.log (baseline 13 classified SIGSEGVs at exact predicted offsets + 175/175 byte-exact leak + 2 behavioral proofs; FIXED half: 0 faults, all clamps visible; byte-identical across run.2.log/run.3.log); build.log (ALL VERBATIM CHECKS PASSED vs guest /usr/src, 24 blocks + bidirectional fix proof); VERDICT.md (full path:line trace); rig/ (pp_rig.c 18 modes, gen_rig.sh, check_verbatim.sh); env.txt (guest md5s = host tree)
PoC changes
fresh rig this run (no prior PoC existed - prior verification was compile-validation + clamp unit test only): guard-backed end-anchored kzalloc shim to make the destination heap OOB write fault decisively; 18-mode driver (16 defect modes + layout + clean-valid regression control); verbatim slice of the whole parser body + 24 header slices with guest-side byte-identity proof
Verified recommended fix
central pp_v1_table_range_ok/pp_v1_clamp_count layer with destination-constant clamps at every offset/count/index consumer (fix.diff, A/B-validated in the rig)
Verdict
REPRODUCED via the DF-4165/4247/4396 verbatim-rig evidence class: the ENTIRE production V1 parser (process_pptables_v1_0.c:34-1337, checker-proven byte-identical on the guest against /usr/src/sys, the tree its running kernel was built from) compiled into a harness and driven with crafted Tonga-format PowerPlay tables. 16 defect modes demonstrated at exactly the predicted verbatim sites, stable across 3 identical runs: (1) heap OOB WRITE in get_vddc_lookup_table (:176-190) - firmware ucNumEntries=255 bounds the copy loop into a fixed kzalloc(4+10*16=164) destination, fault at the first byte past the allocation, up to ~2390B of firmware-chosen content (both usVddcLookupTableOffset and usVddgfxLookupTableOffset paths); (2) six unvalidated USHORT-offset dereferences (state/thermal/fan/sclk-dep/ppm/vce) faulting at image+0xFF00; (3) count-bounded source OOB read loops (sclk 255 vs 3 records); (4) byte-exact kernel-heap leak: MM dep count=40 vs 5 records -> 175/175 parsed field values byte-exact with victim bytes past the image, parse completing into userland-readable DPM tables; (5) VCE ucSCLKIndex=0xFF -> entries[0xFF] read at sclk_table+2+2805; (6) entries[-1] NEGATIVE-INDEX underflow read before the image when ucNumEntries=0 (:1263-1267); (7) entry_index<=ucNumEntries off-by-one (:1310); (8) NULL derefs of vdd_dep_on_sclk in get_pcie_table/get_gpio_table (:522/:745); (9) the never-NULL GPIO gate parsing the PowerPlay header when usGPIOTableOffset==0; (10) num_vce_state_tables stored unclamped (200 vs vce_states[6], :1328). Fix A/B-validated in the same rig: fix.diff (git-apply proven bidirectionally, byte-equal to the packed reference) applied to the same slice -> 0 SIGSEGVs on identical input, counts clamped to image AND destination constants (255->16 lookup, 255->3 sclk, 40->5 mm, 200->6 vce), offsets rejected (rc=-1/-22), indices clamped, entries[-1] gone, NULL guards added, GPIO gate moved to the offset, and clean-valid parses byte-identically in both builds. In-kernel execution is AMD-ASIC-gated on this guest (no 1002: device, hw_probe.log); impact recorded as dos = the realistic in-kernel floor of the demonstrated heap-corruption primitive (panic), with content-controlled overwrite potential; threat model is VBIOS-crafted (flashed ROM / vfio romfile / malicious device) or root-written pp_table, same class as the DF-4247 V0 twin - no unprivileged userland trigger on stock hardware.
No comments yet.