Skip to content

Commit

Permalink
drm: Fix out of bounds access in connector_bad_edid
Browse files Browse the repository at this point in the history
Merge commit 97794170b696 from Linux (by Douglas Anderson):

    drm/edid: In connector_bad_edid() cap num_of_ext by num_blocks read

    In commit e11f5bd8228f ("drm: Add support for DP 1.4 Compliance edid
    corruption test") the function connector_bad_edid() started assuming
    that the memory for the EDID passed to it was big enough to hold
    `edid[0x7e] + 1` blocks of data (1 extra for the base block). It
    completely ignored the fact that the function was passed `num_blocks`
    which indicated how much memory had been allocated for the EDID.

    Let's fix this by adding a bounds check.

    This is important for handling the case where there's an error in the
    first block of the EDID. In that case we will call
    connector_bad_edid() without having re-allocated memory based on
    `edid[0x7e]`.

    Fixes: e11f5bd8228f ("drm: Add support for DP 1.4 Compliance edid corruption test")
    Reported-by: Ville Syrjälä <[email protected]>
    Signed-off-by: Douglas Anderson <[email protected]>
    Reviewed-by: Ville Syrjälä <[email protected]>
    Link: https://patchwork.freedesktop.org/patch/msgid/20211005192905.v2.1.Ib059f9c23c2611cb5a9d760e7d0a700c1295928d@changeid
    Signed-off-by: Dave Airlie <[email protected]>
  • Loading branch information
jrtc27 authored and bsdjhb committed Aug 1, 2024
1 parent 51ea695 commit 13e032a
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions sys/dev/drm/core/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1803,11 +1803,20 @@ static void connector_bad_edid(struct drm_connector *connector,
u8 *edid, int num_blocks)
{
int i;
u8 num_of_ext = edid[0x7e];
u8 last_block;

/*
* 0x7e in the EDID is the number of extension blocks. The EDID
* is 1 (base block) + num_ext_blocks big. That means we can think
* of 0x7e in the EDID of the _index_ of the last block in the
* combined chunk of memory.
*/
last_block = edid[0x7e];

/* Calculate real checksum for the last edid extension block data */
connector->real_edid_checksum =
drm_edid_block_checksum(edid + num_of_ext * EDID_LENGTH);
if (last_block < num_blocks)
connector->real_edid_checksum =
drm_edid_block_checksum(edid + last_block * EDID_LENGTH);

if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
return;
Expand Down

0 comments on commit 13e032a

Please sign in to comment.