AMD General

Reviewed-by: Hawking Zhang <[email protected]>

Regards,
Hawking
-----Original Message-----
From: Lazar, Lijo <[email protected]>
Sent: Monday, June 22, 2026 5:54 PM
To: [email protected]
Cc: Zhang, Hawking <[email protected]>; Deucher, Alexander 
<[email protected]>
Subject: [PATCH] drm/amdgpu: bounds check VBIOS name extraction

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

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

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c 
b/drivers/gpu/drm/amd/amdgpu/atom.c
index d4a652d2b453..ebb4ac279393 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -1358,6 +1358,7 @@ static void atom_index_iio(struct atom_context *ctx, int 
base)  static void atom_get_vbios_name(struct atom_context *ctx)  {
        unsigned char *p_rom;
+       unsigned char *p_end;
        unsigned char str_num;
        unsigned short off_to_vbios_str;
        unsigned char *c_ptr;
@@ -1368,39 +1369,48 @@ static void atom_get_vbios_name(struct atom_context 
*ctx)
        char *back;

        p_rom = ctx->bios;
+       p_end = p_rom + ctx->bios_size;
+
+       if (p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START + 1 >= p_end)
+               goto no_name;

        str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
-       if (str_num != 0) {
-               off_to_vbios_str =
-                       *(unsigned short *)(p_rom + 
OFFSET_TO_GET_ATOMBIOS_STRING_START);
+       if (!str_num)
+               goto no_name;

-               c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
-       } else {
-               /* do not know where to find name */
-               memcpy(ctx->name, na, 7);
-               ctx->name[7] = 0;
-               return;
-       }
+       off_to_vbios_str =
+               *(unsigned short *)(p_rom + 
OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+       c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+       if (c_ptr >= p_end)
+               goto no_name;

        /*
         * skip the atombios strings, usually 4
         * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
         */
        for (i = 0; i < str_num; i++) {
-               while (*c_ptr != 0)
+               while (c_ptr < p_end && *c_ptr != 0)
                        c_ptr++;
                c_ptr++;
        }

        /* skip the following 2 chars: 0x0D 0x0A */
        c_ptr += 2;
+       if (c_ptr >= p_end)
+               goto no_name;

-       name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+       name_size = strnlen(c_ptr, min(STRLEN_LONG - 1, (int)(p_end -
+c_ptr)));
        memcpy(ctx->name, c_ptr, name_size);
        back = ctx->name + name_size;
        while ((*--back) == ' ')
                ;
        *(back + 1) = '\0';
+       return;
+
+no_name:
+       /* do not know where to find name */
+       strscpy(ctx->name, na, sizeof(ctx->name));
 }

 static void atom_get_vbios_date(struct atom_context *ctx)
--
2.49.0

Reply via email to