From: Candice Li Date: Tue, 19 May 2026 09:31:21 +0000 (+0800) Subject: drm/amd/ras: validate RAS EEPROM tbl_size before record count X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e5565e7c3fada97f8b95c9704df80db85feafea4;p=thirdparty%2Flinux.git drm/amd/ras: 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 Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_eeprom.c b/drivers/gpu/drm/amd/ras/rascore/ras_eeprom.c index 34b798f45af2..3a0ea036c9be 100644 --- a/drivers/gpu/drm/amd/ras/rascore/ras_eeprom.c +++ b/drivers/gpu/drm/amd/ras/rascore/ras_eeprom.c @@ -141,12 +141,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_ras_core_context(x) (container_of(x, struct ras_core_context, ras_eeprom)) @@ -1139,11 +1142,24 @@ static int __check_ras_table_status(struct ras_core_context *ras_core) 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) { + RAS_DEV_ERR(ras_core->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 ras_eeprom_reset_table(ras_core); + } 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) { + RAS_DEV_ERR(ras_core->dev, + "RAS header invalid, tbl_size %u smaller than minimum %u, resetting table\n", + hdr->tbl_size, RAS_TABLE_HEADER_SIZE); + return ras_eeprom_reset_table(ras_core); + } control->ras_num_recs = RAS_NUM_RECS(hdr); control->ras_record_offset = RAS_RECORD_START; control->ras_max_record_count = RAS_MAX_RECORD_COUNT;