If RAS header read from EEPROM is corrupted, it could result in trying
to allocate huge memory for reading the records. Add some validation to
header fields.

Signed-off-by: Lijo Lazar <[email protected]>
---
 .../gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c    | 22 ++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
index 0ea7cfaf3587..e979a6086178 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
@@ -1392,17 +1392,33 @@ int amdgpu_ras_eeprom_init(struct 
amdgpu_ras_eeprom_control *control)
 
        __decode_table_header_from_buf(hdr, buf);
 
-       if (hdr->version >= RAS_TABLE_VER_V2_1) {
+       switch (hdr->version) {
+       case RAS_TABLE_VER_V2_1:
+       case RAS_TABLE_VER_V3:
                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;
-       } else {
+               break;
+       case RAS_TABLE_VER_V1:
                control->ras_num_recs = RAS_NUM_RECS(hdr);
                control->ras_record_offset = RAS_RECORD_START;
                control->ras_max_record_count = RAS_MAX_RECORD_COUNT;
+               break;
+       default:
+               dev_err(adev->dev,
+                       "RAS header invalid, unsupported version: %u",
+                       hdr->version);
+               return -EINVAL;
        }
-       control->ras_fri = RAS_OFFSET_TO_INDEX(control, hdr->first_rec_offset);
 
+       if (control->ras_num_recs > control->ras_max_record_count) {
+               dev_err(adev->dev,
+                       "RAS header invalid, records in header: %u max allowed 
:%u",
+                       control->ras_num_recs, control->ras_max_record_count);
+               return -EINVAL;
+       }
+
+       control->ras_fri = RAS_OFFSET_TO_INDEX(control, hdr->first_rec_offset);
        control->ras_num_mca_recs = 0;
        control->ras_num_pa_recs = 0;
        return 0;
-- 
2.25.1

Reply via email to