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