mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
drm/amdgpu: validate RAS EEPROM tbl_size before record count
Corrupt EEPROM data can set tbl_size below the table header size. Guard the RAS_NUM_RECS macros against undersized tbl_size and reset the table during init when tbl_size is below the minimum for the table version instead of trusting the header. Signed-off-by: Candice Li <candice.li@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
e5565e7c3f
commit
c83e4a45ff
|
|
@ -145,12 +145,15 @@
|
|||
#define RAS_RI_TO_AI(_C, _I) (((_I) + (_C)->ras_fri) % \
|
||||
(_C)->ras_max_record_count)
|
||||
|
||||
#define RAS_NUM_RECS(_tbl_hdr) (((_tbl_hdr)->tbl_size - \
|
||||
RAS_TABLE_HEADER_SIZE) / RAS_TABLE_RECORD_SIZE)
|
||||
#define RAS_NUM_RECS(_tbl_hdr) \
|
||||
(((_tbl_hdr)->tbl_size < RAS_TABLE_HEADER_SIZE) ? 0u : \
|
||||
(((_tbl_hdr)->tbl_size - RAS_TABLE_HEADER_SIZE) / RAS_TABLE_RECORD_SIZE))
|
||||
|
||||
#define RAS_NUM_RECS_V2_1(_tbl_hdr) (((_tbl_hdr)->tbl_size - \
|
||||
RAS_TABLE_HEADER_SIZE - \
|
||||
RAS_TABLE_V2_1_INFO_SIZE) / RAS_TABLE_RECORD_SIZE)
|
||||
#define RAS_NUM_RECS_V2_1(_tbl_hdr) \
|
||||
(((_tbl_hdr)->tbl_size < RAS_TABLE_HEADER_SIZE + \
|
||||
RAS_TABLE_V2_1_INFO_SIZE) ? 0u : \
|
||||
(((_tbl_hdr)->tbl_size - RAS_TABLE_HEADER_SIZE - \
|
||||
RAS_TABLE_V2_1_INFO_SIZE) / RAS_TABLE_RECORD_SIZE))
|
||||
|
||||
#define to_amdgpu_device(x) ((container_of(x, struct amdgpu_ras, eeprom_control))->adev)
|
||||
|
||||
|
|
@ -1610,11 +1613,24 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
|
|||
switch (hdr->version) {
|
||||
case RAS_TABLE_VER_V2_1:
|
||||
case RAS_TABLE_VER_V3:
|
||||
if (hdr->tbl_size < RAS_TABLE_HEADER_SIZE + RAS_TABLE_V2_1_INFO_SIZE) {
|
||||
dev_err(adev->dev,
|
||||
"RAS header invalid, tbl_size %u smaller than minimum %u, resetting table\n",
|
||||
hdr->tbl_size,
|
||||
RAS_TABLE_HEADER_SIZE + RAS_TABLE_V2_1_INFO_SIZE);
|
||||
return amdgpu_ras_eeprom_reset_table(control);
|
||||
}
|
||||
control->ras_num_recs = RAS_NUM_RECS_V2_1(hdr);
|
||||
control->ras_record_offset = RAS_RECORD_START_V2_1;
|
||||
control->ras_max_record_count = RAS_MAX_RECORD_COUNT_V2_1;
|
||||
break;
|
||||
case RAS_TABLE_VER_V1:
|
||||
if (hdr->tbl_size < RAS_TABLE_HEADER_SIZE) {
|
||||
dev_err(adev->dev,
|
||||
"RAS header invalid, tbl_size %u smaller than minimum %u, resetting table\n",
|
||||
hdr->tbl_size, RAS_TABLE_HEADER_SIZE);
|
||||
return amdgpu_ras_eeprom_reset_table(control);
|
||||
}
|
||||
control->ras_num_recs = RAS_NUM_RECS(hdr);
|
||||
control->ras_record_offset = RAS_RECORD_START;
|
||||
control->ras_max_record_count = RAS_MAX_RECORD_COUNT;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user