| From 2a53eae79a389c327047acd7e14f93f595a8e183 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 26 Mar 2025 13:28:38 +0530 |
| Subject: drm/amdgpu: Add basic validation for RAS header |
| |
| From: Lijo Lazar <lijo.lazar@amd.com> |
| |
| [ Upstream commit 5df0d6addb7e9b6f71f7162d1253762a5be9138e ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../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 0ea7cfaf3587d..e979a6086178c 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.39.5 |
| |