Bound atom_get_vbios_version() by the BIOS size to avoid out-of-bounds reads.

Signed-off-by: Lijo Lazar <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/atom.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c 
b/drivers/gpu/drm/amd/amdgpu/atom.c
index 07a33f94ed6a..0f6def9c3318 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -1528,8 +1528,10 @@ static void atom_get_vbios_version(struct atom_context 
*ctx)
        unsigned short start = 3, end;
        unsigned char *vbios_ver;
        unsigned char *p_rom;
+       unsigned char *p_end;
 
        p_rom = ctx->bios;
+       p_end = p_rom + ctx->bios_size;
        /* Search from strings offset if it's present */
        start = *(unsigned short *)(p_rom +
                                    OFFSET_TO_GET_ATOMBIOS_STRING_START);
@@ -1546,10 +1548,14 @@ static void atom_get_vbios_version(struct atom_context 
*ctx)
        /* find anchor ATOMBIOSBK-AMD */
        vbios_ver =
                atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, start, end, 64);
-       if (vbios_ver != NULL) {
+
+       if (vbios_ver != NULL && vbios_ver + 18 < p_end) {
                /* skip ATOMBIOSBK-AMD VER */
                vbios_ver += 18;
-               memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
+               /* copy the version, truncating to whatever fits in the image */
+               strscpy(ctx->vbios_ver_str, vbios_ver,
+                       min(sizeof(ctx->vbios_ver_str),
+                           (size_t)(p_end - vbios_ver)));
        } else {
                ctx->vbios_ver_str[0] = '\0';
        }
-- 
2.49.0

Reply via email to