DF-1498 / fix.diff
diff --git a/sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c b/sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c --- a/sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c +++ b/sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c @@ -1495,6 +1495,18 @@ if ((profile->asHeader.ucTableFormatRevision >= 2) && (profile->asHeader.ucTableContentRevision >= 1) && (profile->asHeader.usStructureSize >= sizeof(ATOM_ASIC_PROFILING_INFO_V2_1))) { + /* Validate that all offsets fall inside the table to + * prevent OOB reads of attacker-controlled BIOS data. */ + if (profile->usLeakageBinArrayOffset + + (profile->ucLeakageBinNum * (uint32_t)sizeof(u16)) > + le16_to_cpu(profile->asHeader.usStructureSize) || + profile->usElbVDDC_IdArrayOffset + + (profile->ucElbVDDC_Num * (uint32_t)sizeof(u16)) > + le16_to_cpu(profile->asHeader.usStructureSize) || + profile->usElbVDDC_LevelArrayOffset + + (profile->ucElbVDDC_Num * profile->ucLeakageBinNum * (uint32_t)sizeof(u16)) > + le16_to_cpu(profile->asHeader.usStructureSize)) + return -EINVAL; leakage_bin = (u16 *)((char *)profile + profile->usLeakageBinArrayOffset); vddc_id_buf = (u16 *)((char *)profile + profile->usElbVDDC_IdArrayOffset); vddc_buf = (u16 *)((char *)profile + profile->usElbVDDC_LevelArrayOffset); |