* [PATCH 22/28] drm/amd/display: Fix integer overflow in bios_get_image()
[not found] <20260513143213.1852892-2-IVAN.LIPSKI@amd.com>
@ 2026-05-13 14:29 ` IVAN.LIPSKI
2026-05-13 14:29 ` [PATCH 23/28] drm/amd/display: Validate GPIO pin LUT table size before iterating IVAN.LIPSKI
2026-05-13 14:29 ` [PATCH 26/28] drm/amd/display: Validate payload length and link_index in dc_process_dmub_aux_transfer_async IVAN.LIPSKI
2 siblings, 0 replies; 3+ messages in thread
From: IVAN.LIPSKI @ 2026-05-13 14:29 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, stable
From: Harry Wentland <harry.wentland@amd.com>
[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: stable@vger.kernel.org
Assisted-by: GitHub Copilot:claude-opus-4.6
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
---
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
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 23/28] drm/amd/display: Validate GPIO pin LUT table size before iterating
[not found] <20260513143213.1852892-2-IVAN.LIPSKI@amd.com>
2026-05-13 14:29 ` [PATCH 22/28] drm/amd/display: Fix integer overflow in bios_get_image() IVAN.LIPSKI
@ 2026-05-13 14:29 ` IVAN.LIPSKI
2026-05-13 14:29 ` [PATCH 26/28] drm/amd/display: Validate payload length and link_index in dc_process_dmub_aux_transfer_async IVAN.LIPSKI
2 siblings, 0 replies; 3+ messages in thread
From: IVAN.LIPSKI @ 2026-05-13 14:29 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, stable
From: Harry Wentland <harry.wentland@amd.com>
[Why&How]
The GPIO pin table parsers in get_gpio_i2c_info() and
bios_parser_get_gpio_pin_info() derive an element count from the VBIOS
table_header.structuresize field, then iterate over gpio_pin[] entries.
However, GET_IMAGE() only validates that the table header itself fits
within the BIOS image. If the VBIOS reports a structuresize larger than
the actual mapped data, the loop reads past the end of the BIOS image,
causing an out-of-bounds read.
Fix this by calling bios_get_image() to validate that the full claimed
structuresize is accessible within the BIOS image before entering the
loop in both functions.
Cc: stable@vger.kernel.org
Assisted-by: GitHub Copilot:claude-opus-4-6 Mythos
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
---
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 9 +++++++++
1 file changed, 9 insertions(+)
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 b4dd8219b8f0..39668db6d472 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -493,6 +493,10 @@ static enum bp_result get_gpio_i2c_info(
- sizeof(struct atom_common_table_header))
/ sizeof(struct atom_gpio_pin_assignment);
+ if (!bios_get_image(&bp->base, DATA_TABLES(gpio_pin_lut),
+ le16_to_cpu(header->table_header.structuresize)))
+ return BP_RESULT_BADBIOSTABLE;
+
pin = (struct atom_gpio_pin_assignment *) header->gpio_pin;
for (table_index = 0; table_index < count; table_index++) {
@@ -681,6 +685,11 @@ static enum bp_result bios_parser_get_gpio_pin_info(
count = (le16_to_cpu(header->table_header.structuresize)
- sizeof(struct atom_common_table_header))
/ sizeof(struct atom_gpio_pin_assignment);
+
+ if (!bios_get_image(&bp->base, DATA_TABLES(gpio_pin_lut),
+ le16_to_cpu(header->table_header.structuresize)))
+ return BP_RESULT_BADBIOSTABLE;
+
for (i = 0; i < count; ++i) {
if (header->gpio_pin[i].gpio_id != gpio_id)
continue;
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 26/28] drm/amd/display: Validate payload length and link_index in dc_process_dmub_aux_transfer_async
[not found] <20260513143213.1852892-2-IVAN.LIPSKI@amd.com>
2026-05-13 14:29 ` [PATCH 22/28] drm/amd/display: Fix integer overflow in bios_get_image() IVAN.LIPSKI
2026-05-13 14:29 ` [PATCH 23/28] drm/amd/display: Validate GPIO pin LUT table size before iterating IVAN.LIPSKI
@ 2026-05-13 14:29 ` IVAN.LIPSKI
2 siblings, 0 replies; 3+ messages in thread
From: IVAN.LIPSKI @ 2026-05-13 14:29 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, stable
From: Harry Wentland <harry.wentland@amd.com>
[Why&How]
dc_process_dmub_aux_transfer_async() copies payload->length bytes into a
16-byte stack buffer (dpaux.data[16]) guarded only by an ASSERT(), which
is a no-op in release builds. If a caller ever passes length > 16 this
results in a stack buffer overflow via memcpy.
Additionally, link_index is used to dereference dc->links[] without
bounds checking against dc->link_count, risking an out-of-bounds access.
Replace the ASSERT with a hard runtime check that returns false when
payload->length exceeds the destination buffer size, and add a bounds
check for link_index before it is used.
Cc: stable@vger.kernel.org
Assisted-by: GitHub Copilot:Claude claude-4-opus
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 48d32adb9eb3..0f37209c8330 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -6615,7 +6615,11 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
uint8_t action;
union dmub_rb_cmd cmd = {0};
- ASSERT(payload->length <= 16);
+ if (link_index >= dc->link_count || !dc->links[link_index])
+ return false;
+
+ if (payload->length > sizeof(cmd.dp_aux_access.aux_control.dpaux.data))
+ return false;
cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS;
cmd.dp_aux_access.header.payload_bytes = 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread