vega10 backend-init NULL-derefs optional pptable subtables (tdp/mm/lookup/dep tables) β missing-offset VBIOS panics the kernel (DF-3685 twin)
Summary
vega10_pp_tables_initialize NULL-initializes every subtable pointer and only parses one when its us*TableOffset is nonzero, returning SUCCESS with NULL pointers. vega10_hwmgr_backend_init then dereferences them before any NULL assert: vega10_set_features_platform_caps 'table_info->tdp_table->usClockStretchAmount', and vega10_patch_voltage_dependency_tables_with_lookup_table for all six dep tables plus the vddc/vddci/vddmem lookup entries and mm_table->count - all run BEFORE the only NULL asserts in the path. Crafted/malformed VBIOS (zero offsets) on a Vega10 -> deterministic NULL-deref panic at amdgpu attach: boot-time or hotplug local DoS.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3702 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.0 KB | β raw | |
| VERDICT.md | β | 2.5 KB | β raw | |
| trigger_notes.c | β | 1.5 KB | view raw | |
| build.sh | β | 134 B | view raw | |
| run.sh | β | 167 B | view raw | |
| run.log | β | 1.3 KB | view raw | |
| env.txt | β | 848 B | view raw | |
| fix.diff | β | 1.7 KB | view raw | |
| manifest.json | β | 1.1 KB | view raw | |
| verdict.json | β | 2.8 KB | view raw |
DF-3702 β vega10 backend-init dereferences optional pptable subtables without NULL checks (missing-offset VBIOS => NULL-deref panic)
File: sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c (pass 2). smu7 checklist item (c) β DF-3685 vega10 twin.
Root cause
vega10_pp_tables_initialize (vega10_processpptables.c:905-922, verified in guest src) initializes
every subtable pointer to NULL and only parses a subtable when its offset field in the ATOM
powerplay table is non-zero; a zero offset leaves the pointer NULL and result == 0 (success).
Later, vega10_hwmgr_backend_init dereferences those pointers unconditionally, BEFORE the only
NULL asserts in the path (vega10_set_private_data_based_on_pptable :754-762 runs at :879):
vega10_set_features_platform_caps:269 βtable_info->tdp_table->usClockStretchAmount(called from backend_init :862). tdp_table is NULL whenusPowerTuneTableOffset == 0.vega10_complete_dependency_tables(backend_init :876) βvega10_patch_voltage_dependency_tables_with_lookup_table:635-686: - :658vdt->count/ :659vdt->entries[entry_id]for all six dep tables (socclk/gfxclk/dcefclk/pixclk/dispclk/phyclk) β any NULL offset => deref, - :661table_info->vddc_lookup_table->entries[...]β NULL when usVddcLookupTableOffset == 0, - :665mm_table->countβ NULL when usMMDependencyTableOffset == 0, - :677vddci_lookup_table->entries[...], :680vddmem_lookup_table->entries[...]β NULL when the respective offsets are 0 (loop over mclk entries runs unconditionally).
Trigger (requires AMD Vega10 hardware)
Craft VBIOS powerplay table: zero one or more of usPowerTuneTableOffset / us*DependencyTableOffset / usVddcLookupTableOffset / usVddciLookupTableOffset / usVddmemLookupTableOffset / usMMDependencyTableOffset (keep VDDC SVID2 atomfirmware objects intact so backend_init reaches :862). Driver attach β immediate NULL-deref kernel panic (DoS at boot/hotplug).
PoC status
Guest virtio-only (env.txt) β amdgpu never binds; status inconclusive, source-certain.
DF-3702 VERDICT β NULL subtable derefs at backend init
status: inconclusive (hardware-gated) β source-certain. reproduced=0 on audit guest.
Proof chain (all lines verified byte-identical in guest /usr/src, see run.log)
- Parser: vega10_processpptables.c:905-913 sets all 9 subtable pointers NULL;
:916-922 (and the following identical guards for socclk/gfxclk/pix/phy/disp/dcef/mclk,
pcie, hardlimit, and :1107-1128 for the three lookup tables) only populate a pointer
when
powerplay_table->us<Table>Offset != 0; offsets of 0 do NOT fail the parse. hwmgr_hw_init(hwmgr.c:222-229) calls pptable_init first, then backend_init.vega10_hwmgr_backend_init: - :862vega10_set_features_platform_capsβ :269table_info->tdp_table->usClockStretchAmountβ NULL tdp_table (usPowerTuneTableOffset==0) β NULL+offset deref β panic. - :876vega10_complete_dependency_tablesβ :734vega10_patch_voltage_dependency_tables_with_lookup_tableβ :658vdt->countfor each of the 6 dep tables, :661 vddc_lookup_table, :665 mm_table, :677/:680 vddci/vddmem lookups β any of them NULL β panic. This runs BEFORE :879vega10_set_private_data_based_on_pptable, whose :754-762 asserts are the only NULL checks in the whole path (and even they only cover vdd_dep_on_socclk and vdd_dep_on_mclk).- Contrast: the smu10/vega12 families and the later upstream vega10 code add explicit
PP_ASSERT_WITH_CODE(table_info->x, ...)guards; this file has none for tdp/mm/lookup and relies on deref order.
Impact: crafted-VBIOS (flash / malicious eGPU / VFIO passthrough) β deterministic kernel NULL-deref panic during amdgpu attach β local DoS (boot-time or hotplug). Not memory corruption beyond the fault; severity Medium.
Guest result
0 AMD PCI devices; amdgpu.ko present but never binds; the panic cannot be produced on this guest. Cited lines confirmed present in guest /usr/src (run.log). Honest verdict: inconclusive (hardware-gated), source-certain.
Fix
fix.diff adds NULL guards (assert+skip / assert+return -EINVAL) at :269 and in the patch loop for each table, mirroring the set_private_data asserts.
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
not_testablefix.diff authored against read-only sys/ tree; no AMD hw on guest so no patched-kernel validation possible
fix.diff; run.log hardware gate
Confirmed kernel references
- sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:269
- sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:658
- sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:661
- sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:665
- sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:677
- sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:876
- sys/dev/drm/amd/powerplay/hwmgr/vega10_processpptables.c:905
Detail
Exploit chain
crafted VBIOS (missing PowerTune/dep/lookup/MM offsets) -> amdgpu attach -> vega10_hwmgr_backend_init :862/:876 -> NULL deref -> panic (DoS); no control-flow hijack demonstrated
Evidence (decisive lines)
VERDICT.md proof chain; run.log (guest-src excerpts :269,:658-661, parser NULL-init 905-922); trigger_notes.c (blob recipe); fix.diff
PoC changes
no runnable PoC possible (hardware-gated); documented the exact VBIOS offset fields to zero; verified cited lines in guest kernel source
Verified recommended fix
Add NULL guards before :269 and inside vega10_patch_voltage_dependency_tables_with_lookup_table (skip absent optional tables; -EINVAL for mandatory ones), mirroring :754-762 asserts
Verdict
Source-certain NULL-pointer dereference at driver attach (DF-3685 smu7 twin): vega10_pp_tables_initialize (vega10_processpptables.c:905-922,1107-1128) leaves optional subtable pointers NULL when the corresponding us*TableOffset is 0 and still returns success; vega10_hwmgr_backend_init then dereferences table_info->tdp_table at vega10_hwmgr.c:269 (via :862) and the six dep tables + vddc/vddci/vddmem lookup tables + mm table at :658/:661/:665/:677/:680 (via :876->:734), all before the only NULL asserts in the path (:754-762, reached at :879). Crafted-VBIOS Vega10 -> deterministic kernel panic at attach (DoS). Not reproducible on the audit guest (0 AMD PCI devices; amdgpu.ko present but never binds); cited lines verified byte-identical in guest /usr/src.
No comments yet.