On Tue, 23 Jun 2026, Naveed Khan <[email protected]> wrote:
> drm_parse_tiled_block() casts the generic DisplayID data block to
> struct displayid_tiled_block and unconditionally reads the whole
> fixed-size structure (tile_cap, topo[3], tile_size[4],
> tile_pixel_bezel[5] and the 8-byte topology_id), but it never looks at
> block->num_bytes.
>
> The DisplayID iterator in displayid_iter_block() only guarantees that the
> block's *declared* length, sizeof(struct displayid_block) + num_bytes,
> fits inside the section. A DisplayID extension that declares a tiled
> display block (tag DATA_BLOCK_TILED_DISPLAY) with a num_bytes smaller than
> the structure payload is therefore happily handed to the parser, which
> then reads past the declared block. When such a block is placed near the
> end of the last DisplayID EDID extension, the over-read runs past the end
> of the EDID allocation - an out-of-bounds read controlled entirely by the
> contents of the EDID.
>
> Reject tiled blocks that are too short to hold the structure, mirroring
> the size check already done for the VESA vendor block in
> drm_parse_vesa_mso_data().
Already fixed by commit faaa1e115583 ("drm/edid: fix OOB read in
drm_parse_tiled_block()").
BR,
Jani.
>
> Signed-off-by: Naveed Khan <[email protected]>
> ---
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 404208bf23..b4298012eb 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -7575,6 +7575,13 @@ static void drm_parse_tiled_block(struct drm_connector
> *connector,
> u8 num_v_tile, num_h_tile;
> struct drm_tile_group *tg;
>
> + if (block->num_bytes < sizeof(*tile) - sizeof(*block)) {
> + drm_dbg_kms(connector->dev,
> + "[CONNECTOR:%d:%s] Invalid tiled display block size
> %u\n",
> + connector->base.id, connector->name,
> block->num_bytes);
> + return;
> + }
> +
> w = tile->tile_size[0] | tile->tile_size[1] << 8;
> h = tile->tile_size[2] | tile->tile_size[3] << 8;
--
Jani Nikula, Intel