]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu: Add basic validation for RAS header
authorLijo Lazar <lijo.lazar@amd.com>
Wed, 26 Mar 2025 07:58:38 +0000 (13:28 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 7 Apr 2025 19:18:59 +0000 (15:18 -0400)
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 <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c

index 0ea7cfaf3587dfd771a285dfa27bee86c25756c2..e979a6086178c73c0d91b28bf11292faf057e3ea 100644 (file)
@@ -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;