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

NULL mm_dep_table dereference panics: V1 parser leaves the subtable NULL (usMMDependencyTableOffset==0) and vegam_update_uvd/vce_smc_table deref it unconditionally

Summary

The parser sets mm_dep_table=NULL when usMMDependencyTableOffset==0 (well-formed minimal pptable); vegam derefs it at :340 (update_uvd_smc_table, reached whenever UVD DPM is enabled) and :374 (update_vce_smc_table, StablePState path) - NULL kernel deref panic on first video use. The NULL aspect at the populate functions rides DF-1366/67 (excluded). NULL-guard fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4074 Β· 5 files
FileTypeDescriptionSize
verdict.json β€” 2.2 KB view raw
README.md β€” 250 B ↓ raw
VERDICT.md β€” 1.7 KB ↓ raw
fix.diff β€” 611 B view raw
manifest.json β€” 758 B view raw

DF-4074 β€” vegam NULL mm_dep_table dereference panics (pass 2, checklist class d)

Sites: vegam_smumgr.c:340 (vegam_update_uvd_smc_table), :374 (vegam_update_vce_smc_table) Source-level finding. No executable PoC (hardware-gated); see VERDICT.md.

VERDICT.md
↓ download raw

DF-4074 VERDICT β€” source-level certain, hardware-gated

Root cause

  • The V1 pptable parser leaves pp_table_information->mm_dep_table = NULL whenever usMMDependencyTableOffset == 0 (process_pptables_v1_0.c:796-802) β€” a perfectly parseable, well-formed-but-minimal VBIOS powerplay table.
  • vegam dereferences it with no NULL check: vegam_smumgr.c:340 if (table_info->mm_dep_table->count > 0) β€” vegam_update_uvd_smc_table() vegam_smumgr.c:374 smc_state_table.VceBootLevel = (uint8_t)(table_info->mm_dep_table->count - 1) (StablePState path) β€” vegam_update_vce_smc_table()
  • Reachability: vegam_update_smc_table() dispatches SMU_UVD_TABLE / SMU_VCE_TABLE to these helpers; the smu7 hwmgr invokes them when UVD/VCE DPM is enabled (video encode/decode use).
  • NULL kernel deref β‡’ panic (local DoS with such a VBIOS; also count-1 underflow at :374 if a table exists with count==0, but the parser asserts ucNumEntries != 0 β€” NULL is the realistic path).

Scope discipline

  • :1217 / :1330 (populate vce/uvd level) also deref mm_table, but those FUNCTIONS are DF-1366/67 β€” only their NULL aspect shares this root; not re-filed.
  • vddc_lookup_table NULL at :515 is inside DF-1368's function β€” excluded.

Fix

NULL-guard in both helpers (return 0 with a dev_info, matching the polaris-family fix pattern).

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_testable
baseline no→ patch + rebuild →patched clean

Hardware-gated finding (no AMD VegaM GPU / no LSI mps controller on the audit guest): fix authored at source level (fix.diff) but not build/boot-validated.

fix.diff in this pack; authored post-analysis, not hardware-validated.
↓ fix.diffper-fix-DF-4074

Confirmed kernel references

Detail

Evidence (decisive lines)

process_pptables_v1_0.c:796 'pp_table_information->mm_dep_table = NULL' + :800 conditional init; vegam_smumgr.c:340 and :374 unconditional deref

PoC changes

n/a (source-level)

Verified recommended fix

NULL-guard mm_dep_table in both update_*_smc_table() helpers (return 0 with a dev_info, as the polaris fix did).

Verdict

Source-level certain, hardware-gated NULL-deref panic. The V1 pptable parser leaves table_info->mm_dep_table == NULL when usMMDependencyTableOffset == 0 (process_pptables_v1_0.c:796-802). vegam dereferences it unconditionally: vegam_update_uvd_smc_table():340 'table_info->mm_dep_table->count' (reached via vegam_update_smc_table(SMU_UVD_TABLE) whenever UVD DPM is enabled) and vegam_update_vce_smc_table():374 under PHM_PlatformCaps_StablePState. NULL kernel deref => panic/DoS on first UVD (video) use with such a table. The NULL aspect at :1217/:1330 rides the same optional-table root but those functions' count walks are DF-1366/DF-1367 (not re-reported). The vddc_lookup_table NULL deref at :515 sits inside DF-1368's function (excluded).