โฌข DragonFlyBSD Kernel Audit
DF-4040 / run.log
โ† back to finding โ†“ download raw
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.