NULL-subtable dereference family at backend init: V1 parser treats mm/lookup/PowerTune subtables as optional, smu7 derefs them unconditionally with ignored error returns
Summary
init_clock_voltage_dependency/init_dpm_2_parameters only fill mm_dep_table, vddc/vddgfx_lookup_table and cac_dtp_table when the VBIOS offsets are non-zero and still return success when absent. smu7_hwmgr_backend_init ignores the return codes of smu7_complete_dependency_tables/smu7_set_private_data_based_on_pptable_v1 and the code derefs mm_table->count, lookup_table->entries[], cac_dtp_table - kernel panic at driver load or first temperature-range sysfs read. HARNESS-VERIFIED: walks the parse-legal NULL chain and flags the five reachable deref sites. Crafted VBIOS zeroing subtable offsets panics the kernel during amdgpu driver load (DoS); distinct subtables from parser-side DF-1575.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3685 Β· 11 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.6 KB | β raw | |
| VERDICT.md | β | 3.6 KB | β raw | |
| null_subtable_deref.c | β | 3.8 KB | view raw | |
| build.sh | β | 113 B | view raw | |
| run.sh | β | 154 B | view raw | |
| build.log | β | 74 B | view raw | |
| run.log | β | 726 B | view raw | |
| env.txt | β | 1.1 KB | view raw | |
| fix.diff | β | 2.1 KB | view raw | |
| verdict.json | β | 3.6 KB | view raw | |
| manifest.json | β | 1.1 KB | view raw |
DF-3685 β NULL-subtable dereference family at smu7 backend init: V1 parser treats dependency/lookup/PowerTune subtables as optional, smu7 derefs them unconditionally
File: sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c (pass 2, GLM 5.3 re-audit)
Severity: Medium | CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H | CWE: CWE-476 NULL Pointer Dereference | Confidence: certain (source)
What this is
Source-certain NULL-deref family; runtime-inconclusive on this guest (no AMD GPU). The V1 parser only fills mm_dep_table / vddc+vddgfx_lookup_table / cac_dtp_table / vdd_dep_on_sclk / vdd_dep_on_mclk when the matching VBIOS PP-table offset is non-zero and still returns success when they are absent (process_pptables_v1_0.c:794-845, :281-297, :800-806). smu7_hwmgr_backend_init (:2560-2566) then ignores the return codes of smu7_complete_dependency_tables() and smu7_set_private_data_based_on_pptable_v1() and limps on: smu7_patch_voltage_dependency_tables_with_lookup_table derefs mm_table->count (:1878) and vddc/vddgfx_lookup_table->entries[] (:1862/:1868/:1875/:1881); smu7_patch_lookup_table_with_leakage derefs lookup_table->count (:1823) via :2027-2037; smu7_thermal_parameter_init derefs cac_dtp_table (:2183); smu7_get_thermal_temperature_range derefs cac_dtp_table on sysfs temp read (:4764); smu7_init_dpm_defaults derefs cac_dtp_table under the PP_CLOCK_STRETCH feature bit (:1664-1665). A crafted VBIOS zeroing those offsets panics the kernel at driver load (or on first temperature-range sysfs read). Note: a NULL vdd_dep_on_sclk alone already faults earlier inside the parser itself - that specific instance is DF-1575 (process_pptables_v1_0.c); this finding covers the subtables the parser does NOT touch. Harness reproduces the parse-legal NULL chain and flags the five reachable deref sites.
Reproduce (harness on the audit QEMU guest)
scp -F dfbsd-qemu/config null_subtable_deref.c dfbsd-maxx:/tmp/DF-3685/ ssh -F dfbsd-qemu/config dfbsd-maxx 'cd /tmp/DF-3685 && cc -Wall -O0 -o t null_subtable_deref.c && ./t'
Expected: the run prints the confirmed-primitive line (RESULT: ... CONFIRMED ...).
See run.log (and run.2.log where present) for the decisive captured output,
build.log for the guest toolchain transcript, env.txt for the guest environment
(virtio-only, no AMD GPU β pciconf -l shows only 0x1237/0x1111 QEMU devices;
drm.ko/amdgpu.ko exist in /boot/kernel but are not loaded and have no hardware
to bind), which is why the in-kernel trigger itself is inconclusive on this guest.
Fix
fix.diff (authored against the read-only sys/ tree; never applied there).
DF-3685 β verdict narrative
Finding
Source-certain NULL-deref family; runtime-inconclusive on this guest (no AMD GPU). The V1 parser only fills mm_dep_table / vddc+vddgfx_lookup_table / cac_dtp_table / vdd_dep_on_sclk / vdd_dep_on_mclk when the matching VBIOS PP-table offset is non-zero and still returns success when they are absent (process_pptables_v1_0.c:794-845, :281-297, :800-806). smu7_hwmgr_backend_init (:2560-2566) then ignores the return codes of smu7_complete_dependency_tables() and smu7_set_private_data_based_on_pptable_v1() and limps on: smu7_patch_voltage_dependency_tables_with_lookup_table derefs mm_table->count (:1878) and vddc/vddgfx_lookup_table->entries[] (:1862/:1868/:1875/:1881); smu7_patch_lookup_table_with_leakage derefs lookup_table->count (:1823) via :2027-2037; smu7_thermal_parameter_init derefs cac_dtp_table (:2183); smu7_get_thermal_temperature_range derefs cac_dtp_table on sysfs temp read (:4764); smu7_init_dpm_defaults derefs cac_dtp_table under the PP_CLOCK_STRETCH feature bit (:1664-1665). A crafted VBIOS zeroing those offsets panics the kernel at driver load (or on first temperature-range sysfs read). Note: a NULL vdd_dep_on_sclk alone already faults earlier inside the parser itself - that specific instance is DF-1575 (process_pptables_v1_0.c); this finding covers the subtables the parser does NOT touch. Harness reproduces the parse-legal NULL chain and flags the five reachable deref sites.
Root cause (kernel references)
sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1878sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1823sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:2560sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:2183sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:4764sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:794sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:281
What was verified, and how
- 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.
- Harness on the guest (DragonFly 6.5-DEVELOPMENT x86_64,
ccbase toolchain):null_subtable_deref.creproduces the exact kernel code shape and/or arithmetic with 1:1 struct layouts. Output inrun.log. Compiled with-O0β at-O2the compiler detects the array-index UB and misoptimizes the accounting loops (itself a hint of what the kernel code does). - 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.
Fix verification
not_testablefix.diff authored against the read-only sys/ tree after source+harness verification; not built (no AMD hardware on guest).
findings/poc/DF-3685/fix.diff
Confirmed kernel references
- sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1878
- sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:1823
- sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:2560
- sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:2183
- sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:4764
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:794
- sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c:281
Detail
Evidence (decisive lines)
run.log: 'pp_tables_v1_0_initialize returned 0 (parse SUCCEEDS)' followed by five 'NULL DEREF at smu7_hwmgr.c:...' site listings; VERDICT.md; fix.diff (NULL guards + error propagation at :2560-2566)
PoC changes
No seed; wrote a control-flow harness emulating the parser's offset==0 -> NULL -> rc=0 behaviour and walking the smu7 deref chain (no fault executed).
Verified recommended fix
Validate the mandatory V1 subtables in smu7_complete_dependency_tables (return -EINVAL on NULL mm/lookup/cac tables), propagate the error out of smu7_hwmgr_backend_init instead of ignoring it, and NULL-guard cac_dtp_table at :2183/:4764/:1665.
Verdict
Source-certain NULL-deref family; runtime-inconclusive on this guest (no AMD GPU). The V1 parser only fills mm_dep_table / vddc+vddgfx_lookup_table / cac_dtp_table / vdd_dep_on_sclk / vdd_dep_on_mclk when the matching VBIOS PP-table offset is non-zero and still returns success when they are absent (process_pptables_v1_0.c:794-845, :281-297, :800-806). smu7_hwmgr_backend_init (:2560-2566) then ignores the return codes of smu7_complete_dependency_tables() and smu7_set_private_data_based_on_pptable_v1() and limps on: smu7_patch_voltage_dependency_tables_with_lookup_table derefs mm_table->count (:1878) and vddc/vddgfx_lookup_table->entries[] (:1862/:1868/:1875/:1881); smu7_patch_lookup_table_with_leakage derefs lookup_table->count (:1823) via :2027-2037; smu7_thermal_parameter_init derefs cac_dtp_table (:2183); smu7_get_thermal_temperature_range derefs cac_dtp_table on sysfs temp read (:4764); smu7_init_dpm_defaults derefs cac_dtp_table under the PP_CLOCK_STRETCH feature bit (:1664-1665). A crafted VBIOS zeroing those offsets panics the kernel at driver load (or on first temperature-range sysfs read). Note: a NULL vdd_dep_on_sclk alone already faults earlier inside the parser itself - that specific instance is DF-1575 (process_pptables_v1_0.c); this finding covers the subtables the parser does NOT touch. Harness reproduces the parse-legal NULL chain and flags the five reachable deref sites.
No comments yet.