From: Harry Wentland <[email protected]>

[Why&How]
The bounds check in bios_get_image() computes 'offset + size' using
unsigned 32-bit arithmetic before comparing against bios_size. If a
VBIOS image contains a near-UINT32_MAX offset the addition wraps to a
small value, the comparison passes, and the function returns a wild
pointer past the VBIOS mapping.

Additionally, the comparison uses '<' (strict), which incorrectly
rejects the valid exact-fit case where offset + size == bios_size.

Fix both issues by restructuring the check to avoid the addition
entirely: first reject if offset alone exceeds bios_size, then check
size against the remaining space (bios_size - offset). This eliminates
the overflow and correctly permits exact-fit accesses.

Cc: [email protected]

Assisted-by: GitHub Copilot:claude-opus-4.6

Reviewed-by: Alex Hung <[email protected]>
Signed-off-by: Harry Wentland <[email protected]>
Signed-off-by: Ivan Lipski <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c 
b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
index 8d2cf95ae739..e00dc05c2d9d 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
@@ -37,10 +37,13 @@ uint8_t *bios_get_image(struct dc_bios *bp,
        uint32_t offset,
        uint32_t size)
 {
-       if (bp->bios && offset + size < bp->bios_size)
-               return bp->bios + offset;
-       else
+       if (!bp->bios)
                return NULL;
+
+       if (offset > bp->bios_size || size > bp->bios_size - offset)
+               return NULL;
+
+       return bp->bios + offset;
 }
 
 #include "reg_helper.h"
-- 
2.43.0

Reply via email to