β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-4002

Unclamped VBIOS MM-dependency count overflows fiji UvdLevel[8]/VceLevel[8]/AcpLevel[8] SMC arrays

Summary

DF-1271/1296/1346/1366 family, fiji variant: VceLevelCount/UvdLevelCount/AcpLevelCount = (uint8_t)mm_dep_table->count and the walks write past the fixed [8] arrays - 12x12B/12x12B/12x16B past at count 20; ~3KB past the fiji_smumgr allocation at 255. Reached unconditionally from fiji_init_smc_table. NULL-check + clamp fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4002 Β· 8 files
FileTypeDescriptionSize
README.md β€” 1.7 KB ↓ raw
VERDICT.md β€” 1.6 KB ↓ raw
build.sh β€” 65 B view raw
run.sh β€” 89 B view raw
run.log β€” 3.8 KB view raw
env.txt β€” 493 B view raw
fix.diff β€” 7.7 KB view raw
trigger_analysis.c β€” 17.3 KB view raw

DF-4002 β€” Unclamped VBIOS MM-dependency count overflows fiji UvdLevel[8]/VceLevel[8]/AcpLevel[8] SMC arrays

File: sys/dev/drm/amd/powerplay/smumgr/fiji_smumgr.c Class: kernel heap OOB write (memcorrupt) β€” DF-1271 (tonga) / DF-1296 (ci) / DF-1346 (polaris10) / DF-1366-67 (vegam) family, fiji variant Severity: High Β· Confidence: certain (source) Β· runtime hardware-gated

Build / Run / Expected

Same demonstrator as DF-4001 (./build.sh && ./run.sh, section === DF-4002 ===):

VceLevel[8]:  mm_count=20 -> 12 OOB writes, 144 bytes past
AcpLevel[8]:  mm_count=20 -> 12 OOB writes, 144 bytes past
UvdLevel[8]:  mm_count=20 -> 12 OOB writes, 192 bytes past

Source chain

table_info->mm_dep_table->count = VBIOS ucNumEntries (u8 ≀ 255) verbatim (process_pptables_v1_0.c:698-712); fiji pinned to this parser (hwmgr.c:86/127). Consumers index fixed arrays without any clamp: - fiji_populate_smc_vce_level β€” table->VceLevelCount = (uint8_t)(mm_table->count) (:1433), walk :1436-1457 writes VceLevel[count] (SMU73_Discrete_ExtClkLevel 12 B Γ— 8, smu73_discrete.h:255) - fiji_populate_smc_acp_level β€” same shape :1472, walk :1475-1494 into AcpLevel[8] (:256) - fiji_populate_smc_uvd_level β€” same shape :1569, walk :1572-1601 into UvdLevel[8] (16 B Γ— 8, :254)

Arrays sit at DpmTable offsets ~+864/+960/+1056 of 1632 B inside the fiji_smumgr kzalloc; count 255 writes ~3 KB past, running off the end of the allocation into adjacent heap. Reached unconditionally from fiji_init_smc_table:1976/1980/1992.

Fix

fix.diff (shared with DF-4001 pack): NULL-check + clamp each populate walk to SMU73_MAX_LEVELS_{VCE,ACP,UVD}. Compile-validated via nativekernel rebuild (fix_build.log).

VERDICT.md
↓ download raw

VERDICT β€” DF-4002

Status: inconclusive at runtime (hardware-gated); source-certain.

Reproduced in the guest demonstrator (run.log, section DF-4002): with mm_dep_table->count = 20 (a single VBIOS byte, max 255), the exact walk shape of fiji_populate_smc_vce_level (fiji_smumgr.c:1436-1457) writes 12 Γ— 12 B past VceLevel[8]; the ACP twin (:1475-1494) 12 Γ— 12 B past AcpLevel[8]; the UVD twin (:1572-1601) 12 Γ— 16 B past UvdLevel[8] β€” all inside the heap-resident smc_state_table of the fiji_smumgr kzalloc (:339), running off the allocation at count 255 (~3 KB). Count provenance: process_pptables_v1_0.c:698-712 (mm_table->count = mm_dependency_table->ucNumEntries, no clamp anywhere); fiji pinned to this parser at hwmgr.c:86/127. Sinks reached unconditionally from fiji_init_smc_table:1976/1980/1992.

No in-kernel observation possible: guest has no AMD GPU (env.txt). Trigger context = crafted vBIOS / hostile eGPU at driver attach β€” DF-1271 (tonga) / DF-1296 (ci) / DF-1346 (polaris10) / DF-1366-67 (vegam) family, fiji variant; those siblings were rated High, likewise here.

Fix: fix.diff NULL-checks and clamps each walk to SMU73_MAX_LEVELS_{VCE,ACP,UVD}; applied to guest /usr/src, full nativekernel rebuild OK (fix_build.log), reverted.

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

fixed
baseline no→ patch + rebuild →patched clean

fixed (compile-validated): both diffs applied to clean guest /usr/src (fiji_smumgr.c md5 800babd0..->d50bdc81.., i915_gem_execbuffer.c 334c7bd9..->dc882976..), make nativekernel KERNCONF=X86_64_GENERIC completed with error_count=0 under -Werror (fix_build.log); behavior additionally model-verified for DF-4007 (PATCHED run balanced). Runtime re-test impossible on this guest (no AMD/Intel GPU). Patch reverted after validation.

findings/poc/DF-4002/fix.diff; findings/poc/DF-4001/fix_build.log; findings/poc/DF-4007/run.log (PATCHED model run for DF-4007)
↓ fix.diffDragonFly dfbsd 6.5-DEVELOPMENT (nativekernel X86_64_GENERIC, patched, -Werror; see fix_build.log)

Confirmed kernel references

Detail

Exploit chain

crafted vBIOS -> attach/resume -> fiji_init_smc_table -> Uvd/Vce/Acp level populate with ucNumEntries>8 -> heap OOB write past the fiji_smumgr allocation

Evidence (decisive lines)

run.log (DF-4002 section: 12x12B/12x12B/12x16B past Vce/Acp/UvdLevel[8] at count 20); VERDICT.md; fix_build.log; env.txt

PoC changes

Pass-2 reviewer authored demonstrator compiling the kernel's own smu73.h/smu73_discrete.h (packed) so sizeof/offsets are the kernel's; fix.diff generated mechanically against the pristine file and compile-validated via full nativekernel rebuild on the guest (shared build with DF-4001..DF-4007).

Verified recommended fix

NULL-check and clamp mm_dep_table->count to SMU73_MAX_LEVELS_{VCE,ACP,UVD} in the three populate functions (fix.diff)

Verdict

Source-certain heap OOB write, DF-1271/1296/1346/1366 family on fiji: mm_dep_table->count (VBIOS ucNumEntries<=255, process_pptables_v1_0.c:708, no clamp) drives UvdLevel[8]/VceLevel[8]/AcpLevel[8] population (fiji_smumgr.c:1436/1475/1572) inside the fiji_smumgr kzalloc; demonstrator (kernel's own struct sizes) shows 12x12B/12x12B/12x16B past the arrays at count 20, ~3KB past the allocation at 255. Reached unconditionally from fiji_init_smc_table. Hardware-gated (no AMD GPU on guest): inconclusive at runtime, source-certain.