Extended-header fields read before/without usSize gating (usPPMTableOffset at +16 read before V5 check; overdrive limits read with no size gate)
Summary
init_dpm2_parameters evaluates usPPMTableOffset (+16..17) in the condition BEFORE the usSize>=V5 guard; init_overdrive_limits_V2_1 reads the fields with no usSize gate at all - the only getter among its siblings that skips the gate. Within-image OOB reads compounding with DF-1470. Reorder + gate fix (in the central diff).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4249 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.5 KB | β raw | |
| VERDICT.md | β | 1.8 KB | β raw | |
| build.sh | β | 65 B | view raw | |
| env.txt | β | 588 B | view raw | |
| run.log | β | 425 B | view raw | |
| run.sh | β | 89 B | view raw | |
| trigger.sh | β | 468 B | view raw | |
| verdict.json | β | 1.8 KB | view raw |
DF-4249 β Extended-header fields read before/without usSize gate
Where
sys/dev/drm/amd/powerplay/hwmgr/processpptables.c
1. init_dpm2_parameters :1488 β reads extended_header->usPPMTableOffset
(byte offset +16..17 of the extended header) before checking
usSize >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 (:1489-1490). A VBIOS
whose extended header is only V2-sized (12 bytes) still has the field read.
2. init_overdrive_limits_V2_1 :1029-1033 β reads
header->ulMaxEngineClock / ulMaxMemoryClock (+8..15) with no
usSize gate at all, unlike every sibling getter (e.g. get_vce_table_offset
gates on usSize >= V2).
What
Both are within-image OOB reads past the firmware-declared end of the
extended-header sub-table: the parser honors usSize for gating but reads
fields located past it first. Values land in hwmgr->platform_descriptor
(overdrive limits) or select a PPM table offset β no direct leak to
userspace, but the PPM offset then indexes the image and (unpatched) feeds
the unvalidated-offset family (DF-1470).
Trigger
Crafted VBIOS / pp_table with usExtendendedHeaderOffset != 0 and a short
usSize. Hardware-gated (AMD ASIC required).
Fix
Contained in DF-4247/fix.diff:
* PPM: reorder so usSize >= V5 is tested before usPPMTableOffset is read,
plus a pp_table_range_ok check on the PPM table itself.
* V2_1: gate the header deref on usSize >= V3 footprint via
pp_table_range_ok.
Build/run
Hardware-gated; run.sh documents absence of AMD hardware.
DF-4249 VERDICT
status: untested (hardware-gated: no AMD GPU β run.log) impact: none demonstrated (bounded within-image OOB read, Low) confidence: certain (code-trace)
Trace
- processpptables.c:1485-1490:
extended_headeris computed from an unvalidated offset, thenextended_header->usPPMTableOffset(offset 16) is read in the condition while theusSize >= V5(>= 18 bytes) guard is evaluated only afterwards in the same&&chain β C evaluatesusPPMTableOffset > 0first. For an extended header whoseusSizeis 12..15 (V2/V3-sized), bytes 16-17 lie beyond the declared sub-table. - processpptables.c:1029-1033:
init_overdrive_limits_V2_1has nousSizegate whatsoever before readingulMaxEngineClock(offset 4..7) andulMaxMemoryClock(8..11). The sibling getters (get_vce_table_offset:63, get_uvd_table_offset:164, get_samu:229, get_acp:265, get_cacp_tdp:301, get_sclk_vdd_gfx:352) all gate onusSizefirst β this one is the outlier.
Both reads stay inside the surrounding VBIOS image in practice (the extended header sits mid-image), so the practical impact is mis-parsed limits/offset, not a slab overread β rated Low. The PPM offset misuse compounds with DF-1470 until the central layer lands.
Fix
In DF-4247/fix.diff (condition reorder + range checks). fix_status: not_testable (hardware-gated).
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.
(No fix.diff for this item: documented recommendation only - see Fix above.)
Fix verification
not_testablenot_testable: hardware-gated.
reorder+range-check hunk in DF-4247/fix.diff.
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md trace comparing gated siblings (:63,:164,:229,:265,:301,:352); run.log hardware probe.
PoC changes
n/a - pass-2 finding; trigger documentation written fresh (hardware-gated, no seed PoC existed)
Verified recommended fix
gate extended-header field reads on usSize (+range check)
Verdict
Extended-header fields read without/before usSize gating: init_dpm2_parameters:1488 reads usPPMTableOffset (+16) before the usSize>=V5 check in the same condition; init_overdrive_limits_V2_1:1029-1033 reads ulMaxEngineClock/ulMaxMemoryClock with no usSize gate at all (every sibling getter gates). Within-image OOB reads past the declared header; values feed platform limits/PPM offset selection. Low.
No comments yet.