From: Rodrigo Siqueira <rodrigo.sique...@amd.com>

At some point, the IEEE ID identification for the replay check in the
AMD EDID was added. However, this check causes the following
out-of-bounds issues when using KASAN:

[   27.804016] BUG: KASAN: slab-out-of-bounds in 
amdgpu_dm_update_freesync_caps+0xefa/0x17a0 [amdgpu]
[   27.804788] Read of size 1 at addr ffff8881647fdb00 by task systemd-udevd/383

...

[   27.821207] Memory state around the buggy address:
[   27.821215]  ffff8881647fda00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00
[   27.821224]  ffff8881647fda80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00
[   27.821234] >ffff8881647fdb00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc 
fc
[   27.821243]                    ^
[   27.821250]  ffff8881647fdb80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc 
fc
[   27.821259]  ffff8881647fdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00
[   27.821268] 
==================================================================

This is caused because the ID extraction happens outside of the range of
the edid lenght. This commit addresses this issue by considering the
amd_vsdb_block size.

Cc: ChiaHsuan Chung <chiahsuan.ch...@amd.com>
Reviewed-by: Leo Li <sunpeng...@amd.com>
Signed-off-by: Rodrigo Siqueira <rodrigo.sique...@amd.com>
Signed-off-by: Hamza Mahfooz <hamza.mahf...@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1d47719e7af1..8381afbe6e4d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -12096,7 +12096,7 @@ static int parse_amd_vsdb(struct amdgpu_dm_connector 
*aconnector,
                        break;
        }
 
-       while (j < EDID_LENGTH) {
+       while (j < EDID_LENGTH - sizeof(struct amd_vsdb_block)) {
                struct amd_vsdb_block *amd_vsdb = (struct amd_vsdb_block 
*)&edid_ext[j];
                unsigned int ieeeId = (amd_vsdb->ieee_id[2] << 16) | 
(amd_vsdb->ieee_id[1] << 8) | (amd_vsdb->ieee_id[0]);
 
-- 
2.46.1

Reply via email to