DF-4039 / run.log
polaris10_smumgr.c demonstrator โ kernel struct geometry (kernel headers): sizeof(SMU74_Discrete_DpmTable)=1884 GraphicsLevel@+236 MemoryLevel@+708 Sclk_voltageOffset@+1704 BapmVddcVidLoSidd@+176 GraphicsLevel=56B MemoryLevel=24B UvdLevel=16B ExtClkLevel=12B ArbEntry=12B ArbTable(stack)=384B === DF-4036a polaris10_populate_all_graphic_levels -> GraphicsLevel[8] (heap, inside struct polaris10_smumgr) === sclk_count=12: 4 OOB level writes, 224 bytes past GraphicsLevel[8] redzone dirty bytes observed: 224 secondary walk :1028 levels[i].pcieDpmLevel i<count and :1017 GraphicsDpmLevelCount=(u8)count (re-feeds update_dpm_settings:2427) with ucNumEntries=255: 13832 bytes past the array; GraphicsLevel ends 1200B before DpmTable end -> blows past smc_state_table and the polaris10_smumgr kzalloc === DF-4036b polaris10_populate_all_memory_levels -> MemoryLevel[4] (heap) === mclk_count=6: 2 OOB writes, 48 bytes past MemoryLevel[4]; [count-1]=5 store is itself OOB redzone dirty bytes observed: 48 MemoryLevel[4..] overwrite lands on LinkLevel[0..]/ACPILevel/UvdLevel (in-struct) and, from count ~49, past the whole polaris10_smumgr allocation === DF-4036c polaris10_program_memory_timing_parameters -> SMU74_Discrete_MCArbDramTimingTable arb_regs (STACK object) === sclk=12 mclk=6: 72 entry writes total, 26 PAST the 32-entry table (max linear entry 49 of 32) deepest write offset 600B into a 384B stack object -> 216 bytes into the caller frame (216 frame bytes actually smashed here) entries is [8][4]: mclk j>=4 wraps into entries[i+1] (wrong pairing, silent) and runs OFF the table at i==7,j>=4 or i>=8 with ucNumEntries=255/255 the walk reaches offset 15300B past the 384B object (kernel stack smash, return-address direction) === DF-4037 polaris10_populate_cac_table -> BapmVddcVidLoSidd[16] write + vddc_voltage_table.entries[32] read === vddc_lookup_count=40: 24 OOB writes past BapmVddcVidLoSidd[16] (x3 arrays), 8 OOB reads of vddc_voltage_table.entries[32] redzone dirty bytes observed: 0 loop bound is lookup_table->count = raw ucNumEntries (process_pptables_v1_0.c:176; buffer sized for 16 โ DF-1574), while data->vddc_voltage_table was trimmed to SMU74_MAX_LEVELS_VDDC=16 at smu7_hwmgr.c:323-328 โ the read index is bound to neither === DF-4038a polaris10_populate_clock_stretcher_data_table -> Sclk_voltageOffset[8] === dep_sclk->count=12 (RAW count, not the dedup'd dpm count): writes at [8..11] are OOB (skipped here to keep the demo alive) array sits at DpmTable+1704 of 1884B, followed by ClockStretcherDataTable/CKS_LOOKUPTable; count 255 writes 247B past, off smc_state_table walk runs BEFORE the stretch_amount validation (:1579), so even a 'rejected' VBIOS smears the table first === DF-4038b polaris10_populate_avfs_parameters -> sclk dep entries[i < NUM_VFT_COLUMNS=8] read with count < 8 === dep count=3 (< NUM_VFT_COLUMNS=8): 5 reads past the 3-entry heap allocation (cks_voffset + sclk_offset each) values land in AVFS_meanNsigma.Static_Voltage_Offset[]/AVFS_SclkOffset[] and are uploaded to SMU (:1697-1710) === DF-4039 polaris10_get_dependency_volt_by_clk fall-through reads dep_table->entries[i] with i == count (x2) === count=3, i=3 after fall-through; entries[i].vddc read at +60 and entries[i].mvdd at +66 โ past the 3-entry object phantom vddc read = 0x42.. (feeds phm_find_closest_vddci -> MinVoltage to SMU); mvdd read = 0x0001 gates *mvdd === DF-4040 polaris10 populate with usMMDependencyTableOffset==0 / usVddcLookupTableOffset==0 -> NULL derefs === parser leaves mm_dep_table NULL when usMMDependencyTableOffset==0 (result stays 0, parse continues); polaris10_init_smc_table:1819 -> polaris10_populate_smc_vce_level:1298 'table->VceLevelCount=(uint8_t)(mm_table->count)' polaris10_init_smc_table:1831 -> polaris10_populate_smc_uvd_level:1404 'table->UvdLevelCount=(uint8_t)(mm_table->count)' parser leaves vddc_lookup_table NULL when usVddcLookupTableOffset==0 (process_pptables_v1_0.c:281-288); polaris10_init_smc_table:1781 -> polaris10_populate_smc_voltage_tables:728 -> populate_cac_table:712 'lookup_table->count' child took signal 11 on mm_table->count โ in-kernel equivalent: page fault on NULL during polaris10_init_smc_table (attach/resume) => panic === DF-4041 polaris10 MVDD stash: entries[count] wrong-index read (:657) + populate_mvdd_value walk past entries[32] (:1185) === (a) mvdd table count=4: Pattern[0..3].Voltage all read entries[4] -> 0 0 0 0 (expected per-level 1100..1400) โ in-bounds of entries[32] but one past the VALID entries: all MVDD smio patterns programmed with the stale/zero slot (b) vdd_dep_on_mclk->count=40 walking mvdd_voltage_table.entries[32]: 8 reads past the fixed array (intra-struct heap OOB read of smu7_hwmgr); loop breaks early only if a clk matches DEMONSTRATOR COMPLETE: all walks reproduced; counts are single VBIOS bytes (ucNumEntries) reaching the fixed SMU74 SMC arrays unclamped.