Blob Blame History Raw
From: Evan Quan <evan.quan@amd.com>
Date: Tue, 29 May 2018 16:31:05 +0800
Subject: drm/amdgpu: fix parsing indirect register list v2
Git-commit: cb5ed37f1f9976a5f9d5f677ac9423642e30d10f
Patch-mainline: v4.18-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

WARN_ON possible buffer overflow and avoid unnecessary dereference.

v2: change BUG_ON to WARN_ON

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -1838,13 +1838,15 @@ static void gfx_v9_1_parse_ind_reg_list(
 				int indirect_offset,
 				int list_size,
 				int *unique_indirect_regs,
-				int *unique_indirect_reg_count,
+				int unique_indirect_reg_count,
 				int *indirect_start_offsets,
-				int *indirect_start_offsets_count)
+				int *indirect_start_offsets_count,
+				int max_start_offsets_count)
 {
 	int idx;
 
 	for (; indirect_offset < list_size; indirect_offset++) {
+		WARN_ON(*indirect_start_offsets_count >= max_start_offsets_count);
 		indirect_start_offsets[*indirect_start_offsets_count] = indirect_offset;
 		*indirect_start_offsets_count = *indirect_start_offsets_count + 1;
 
@@ -1852,14 +1854,14 @@ static void gfx_v9_1_parse_ind_reg_list(
 			indirect_offset += 2;
 
 			/* look for the matching indice */
-			for (idx = 0; idx < *unique_indirect_reg_count; idx++) {
+			for (idx = 0; idx < unique_indirect_reg_count; idx++) {
 				if (unique_indirect_regs[idx] ==
 					register_list_format[indirect_offset] ||
 					!unique_indirect_regs[idx])
 					break;
 			}
 
-			BUG_ON(idx >= *unique_indirect_reg_count);
+			BUG_ON(idx >= unique_indirect_reg_count);
 
 			if (!unique_indirect_regs[idx])
 				unique_indirect_regs[idx] = register_list_format[indirect_offset];
@@ -1894,9 +1896,10 @@ static int gfx_v9_1_init_rlc_save_restor
 				    adev->gfx.rlc.reg_list_format_direct_reg_list_length,
 				    adev->gfx.rlc.reg_list_format_size_bytes >> 2,
 				    unique_indirect_regs,
-				    &unique_indirect_reg_count,
+				    unique_indirect_reg_count,
 				    indirect_start_offsets,
-				    &indirect_start_offsets_count);
+				    &indirect_start_offsets_count,
+				    ARRAY_SIZE(indirect_start_offsets));
 
 	/* enable auto inc in case it is disabled */
 	tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL));