From: Harry Wentland <[email protected]>

[Why & How]
gpio_bitshift is a uint8_t read directly from the VBIOS GPIO pin table.
If the value is >= 32, the expression "1 << gpio_bitshift" triggers
undefined behaviour in C (shift count exceeds type width). On x86 the
shift is silently masked to 5 bits, producing an incorrect GPIO mask
that may cause wrong MMIO register bits to be toggled.

Validate gpio_bitshift before use and return BP_RESULT_BADBIOSTABLE for
out-of-range values.

Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support")
Cc: [email protected]
Assisted-by: Copilot:claude-opus-4.6

Reviewed-by: Alex Hung <[email protected]>
Signed-off-by: Harry Wentland <[email protected]>
Signed-off-by: Ray Wu <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c 
b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index 6cbdf356b1cd..9fb19f75e934 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -701,8 +701,10 @@ static enum bp_result bios_parser_get_gpio_pin_info(
                info->offset_en = info->offset + 1;
                info->offset_mask = info->offset - 1;
 
-               info->mask = (uint32_t) (1 <<
-                       header->gpio_pin[i].gpio_bitshift);
+               if (header->gpio_pin[i].gpio_bitshift >= 32)
+                       return BP_RESULT_BADBIOSTABLE;
+
+               info->mask = 1u << header->gpio_pin[i].gpio_bitshift;
                info->mask_y = info->mask + 2;
                info->mask_en = info->mask + 1;
                info->mask_mask = info->mask - 1;
-- 
2.43.0

Reply via email to