diff options
| author | Srinivasan Shanmugam <srinivasan.shanmugam@amd.com> | 2026-04-11 21:35:39 +0530 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-04-17 15:24:12 -0400 |
| commit | 0f6d7ec4f1b4febd3f9c6ab39efc25a7cb922cab (patch) | |
| tree | ec948346fbd1dec62947018bac9c8e9de5ed8240 /drivers/gpu | |
| parent | b5245cbe44115d2eb14c2c273771211e1b170c41 (diff) | |
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: 71036457ad85 ("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>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index b04fa9fd90b7..92c98e999efe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -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)) { |
