drm/amdgpu: Clear cached EDID pointer after drm_edid_free()
The driver stores EDID in amdgpu_connector->edid and uses it as a cache.
amdgpu_connector_get_edid() checks this pointer. If it is not NULL, it
assumes EDID is already present and does not read it again.
In some detect paths, the driver frees the EDID using drm_edid_free(),
but does not set the pointer to NULL. Because of this, the pointer still
looks valid even though the memory is already freed.
Later, when amdgpu_connector_get_edid() is called, it returns early and
does not read a new EDID. This can lead to using a freed pointer.
Fix this by setting amdgpu_connector->edid = NULL after drm_edid_free().
This makes sure the driver reads a fresh EDID and does not use invalid
memory.
Fixes: 71036457ad ("drm/amdgpu/amdgpu_connectors: remove amdgpu_connector_free_edid")
Reported-by: Dan Carpenter <error27@gmail.com>
Cc: Joshua Peisach <jpeisach@ubuntu.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Joshua Peisach <jpeisach@ubuntu.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
master
parent
b5245cbe44
commit
0f6d7ec4f1
|
|
@ -866,6 +866,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
|
|||
if (dret) {
|
||||
amdgpu_connector->detected_by_load = false;
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
amdgpu_connector_get_edid(connector);
|
||||
|
||||
if (!amdgpu_connector->edid) {
|
||||
|
|
@ -882,6 +883,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
|
|||
*/
|
||||
if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) {
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
ret = connector_status_disconnected;
|
||||
} else {
|
||||
ret = connector_status_connected;
|
||||
|
|
@ -977,6 +979,7 @@ static void amdgpu_connector_shared_ddc(enum drm_connector_status *status,
|
|||
if (!amdgpu_display_hpd_sense(adev,
|
||||
amdgpu_connector->hpd.hpd)) {
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
*status = connector_status_disconnected;
|
||||
}
|
||||
}
|
||||
|
|
@ -1046,6 +1049,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
|
|||
if (dret) {
|
||||
amdgpu_connector->detected_by_load = false;
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
amdgpu_connector_get_edid(connector);
|
||||
|
||||
if (!amdgpu_connector->edid) {
|
||||
|
|
@ -1062,6 +1066,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
|
|||
*/
|
||||
if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) {
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
ret = connector_status_disconnected;
|
||||
} else {
|
||||
ret = connector_status_connected;
|
||||
|
|
@ -1412,6 +1417,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
|
|||
}
|
||||
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
|
||||
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue