drm/edid: fix invalid EDID extension block filtering
authorJani Nikula <jani.nikula@intel.com>
Wed, 30 Mar 2022 17:04:26 +0000 (20:04 +0300)
committerJani Nikula <jani.nikula@intel.com>
Thu, 31 Mar 2022 09:43:29 +0000 (12:43 +0300)
The invalid EDID block filtering uses the number of valid EDID
extensions instead of all EDID extensions for looping the extensions in
the copy. This is fine, by coincidence, if all the invalid blocks are at
the end of the EDID. However, it's completely broken if there are
invalid extensions in the middle; the invalid blocks are included and
valid blocks are excluded.

Fix it by modifying the base block after, not before, the copy.

Fixes: 14544d0937bf ("drm/edid: Only print the bad edid when aborting")
Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220330170426.349248-1-jani.nikula@intel.com
drivers/gpu/drm/drm_edid.c

index 359c52e5318ae606548352e66847ef843e5c2bd6..18e1b88cd8943f927db3334b9afed4d429a4315b 100644 (file)
@@ -2031,9 +2031,6 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 
                connector_bad_edid(connector, edid, edid[0x7e] + 1);
 
-               edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
-               edid[0x7e] = valid_extensions;
-
                new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
                                    GFP_KERNEL);
                if (!new)
@@ -2050,6 +2047,9 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
                        base += EDID_LENGTH;
                }
 
+               new[EDID_LENGTH - 1] += new[0x7e] - valid_extensions;
+               new[0x7e] = valid_extensions;
+
                kfree(edid);
                edid = new;
        }