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

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

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c 
b/drivers/gpu/drm/amd/amdgpu/atom.c
index ebb4ac279393..5a4b06dfd096 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -1467,12 +1467,17 @@ static unsigned char *atom_find_str_in_rom(struct 
atom_context *ctx, char *str,
 static void atom_get_vbios_pn(struct atom_context *ctx)
 {
        unsigned char *p_rom;
+       unsigned char *p_end;
        unsigned short off_to_vbios_str;
        unsigned char *vbios_str;
        int count;
 
        off_to_vbios_str = 0;
        p_rom = ctx->bios;
+       p_end = p_rom + ctx->bios_size;
+
+       if (p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START + 1 >= p_end)
+               return;
 
        if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
                off_to_vbios_str =
@@ -1483,19 +1488,22 @@ static void atom_get_vbios_pn(struct atom_context *ctx)
                vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
        }
 
+       if (vbios_str >= p_end)
+               return;
+
        if (*vbios_str == 0) {
                vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 
1024, 64);
                if (vbios_str == NULL)
                        vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
        }
        OPTIMIZER_HIDE_VAR(vbios_str);
-       if (vbios_str != NULL && *vbios_str == 0)
+       if (vbios_str != NULL && vbios_str < p_end && *vbios_str == 0)
                vbios_str++;
 
-       if (vbios_str != NULL) {
+       if (vbios_str != NULL && vbios_str < p_end) {
                count = 0;
-               while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' 
&&
-                      vbios_str[count] <= 'z') {
+               while ((count < BIOS_STRING_LENGTH) && &vbios_str[count] < 
p_end &&
+                      vbios_str[count] >= ' ' && vbios_str[count] <= 'z') {
                        ctx->vbios_pn[count] = vbios_str[count];
                        count++;
                }
-- 
2.49.0

Reply via email to