From mboxrd@z Thu Jan 1 00:00:00 1970
From: bugzilla-daemon@freedesktop.org
Subject: [Bug 108609] vegam_smumgr.c: accessing mvdd_voltage_table.entries[]
array out of bounds in function vegam_populate_smc_mvdd_table
Date: Wed, 31 Oct 2018 06:55:41 +0000
Message-ID:
Bug ID
108609
Summary
vegam_smumgr.c: accessing mvdd_voltage_table.entries[] array =
out of bounds in function vegam_populate_smc_mvdd_table
Product
DRI
Version
unspecified
Hardware
x86-64 (AMD64)
OS
Linux (All)
Status
NEW
Severity
normal
Priority
medium
Component
DRM/AMDgpu
Assignee
dri-devel@lists.freedesktop.org
Reporter
rstrube@gmail.com
Created attachment 142298 [details] [review]
Patch to fix accessing mvdd_voltage_table.entries[] array out of bounds in
vegam_smumgr.c
I believe I've discovered a small bug in the vegam_smumgr.c, specifically t=
he
following function:
static int vegam_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr,
SMU75_Discrete_DpmTable *table)
{
struct smu7_hwmgr *data =3D (struct smu7_hwmgr *)(hwmgr->backend=
);
uint32_t count, level;
if (SMU7_VOLTAGE_CONTROL_BY_GPIO =3D=3D data->mvdd_control) {
count =3D data->mvdd_voltage_table.count;
if (count > SMU_MAX_SMIO_LEVELS)
count =3D SMU_MAX_SMIO_LEVELS;
for (level =3D 0; level < count; level++) {
table->SmioTable2.Pattern[level].Voltage =3D
PP_HOST_TO_SMC_US(
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20
data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE);
/* Index into DpmTable.Smio. Drive bits from Smio e=
ntry
to get this voltage level.*/
table->SmioTable2.Pattern[level].Smio =3D
(uint8_t) level;
table->Smio[level] |=3D
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20
data->mvdd_voltage_table.entries[level].smio_low;
}
table->SmioMask2 =3D data->mvdd_voltage_table.mask_lo=
w;
table->MvddLevelCount =3D (uint32_t) PP_HOST_TO_SMC_UL(c=
ount);
}
return 0;
}
With the lines (within the for loop):
table->SmioTable2.Pattern[level].Voltage =3D PP_HOST_TO_SMC_US(
data->mvdd_voltage_table.entries[count].value * VOLTAGE_=
SCALE);
If this code was executed it would try to access the
mvdd_voltage_table.entries[] array out of bounds, because count > than t=
he max
value for level.
I believe:
data->mvdd_voltage_table.entries[count].value
should actually be:
data->mvdd_voltage_table.entries[level].value
You can see in a similar function within vegam_smumgr.c, this bug is *not*
present:
static int vegam_populate_smc_vddci_table(struct pp_hwmgr *hwmgr,
struct SMU75_Discrete_DpmTable *tab=
le)
{
uint32_t count, level;
struct smu7_hwmgr *data =3D (struct smu7_hwmgr *)(hwmgr->backend=
);
count =3D data->vddci_voltage_table.count;
if (SMU7_VOLTAGE_CONTROL_BY_GPIO =3D=3D data->vddci_control) {
if (count > SMU_MAX_SMIO_LEVELS)
count =3D SMU_MAX_SMIO_LEVELS;
for (level =3D 0; level < count; ++level) {
table->SmioTable1.Pattern[level].Voltage =3D
PP_HOST_TO_SMC_US(
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20
data->vddci_voltage_table.entries[level].value * VOLTAGE_SCALE);
table->SmioTable1.Pattern[level].Smio =3D (uint8=
_t)
level;
table->Smio[level] |=3D
data->vddci_voltage_table.entries[level].smio_low;
}
}
table->SmioMask1 =3D data->vddci_voltage_table.mask_low;
return 0;
}
I've attached a patch for kernel 4.19, admittedly the change is trivial but=
I
figured I would try to do things the right way :)
Thanks!
Rob