| From 05d05ad4b5f7b997af4ec969a38236746a28bf2b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 3 Dec 2021 00:17:36 +0800 |
| Subject: drm/amdgpu: Fix a NULL pointer dereference in |
| amdgpu_connector_lcd_native_mode() |
| |
| From: Zhou Qingyang <zhou1615@umn.edu> |
| |
| [ Upstream commit b220110e4cd442156f36e1d9b4914bb9e87b0d00 ] |
| |
| In amdgpu_connector_lcd_native_mode(), the return value of |
| drm_mode_duplicate() is assigned to mode, and there is a dereference |
| of it in amdgpu_connector_lcd_native_mode(), which will lead to a NULL |
| pointer dereference on failure of drm_mode_duplicate(). |
| |
| Fix this bug add a check of mode. |
| |
| This bug was found by a static analyzer. The analysis employs |
| differential checking to identify inconsistent security operations |
| (e.g., checks or kfrees) between two code paths and confirms that the |
| inconsistent operations are not recovered in the current function or |
| the callers, so they constitute bugs. |
| |
| Note that, as a bug found by static analysis, it can be a false |
| positive or hard to trigger. Multiple researchers have cross-reviewed |
| the bug. |
| |
| Builds with CONFIG_DRM_AMDGPU=m show no new warnings, and |
| our static analyzer no longer warns about this code. |
| |
| Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") |
| Signed-off-by: Zhou Qingyang <zhou1615@umn.edu> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |
| index 0de66f59adb8a..df1f9b88a53f9 100644 |
| --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |
| +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |
| @@ -387,6 +387,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder) |
| native_mode->vdisplay != 0 && |
| native_mode->clock != 0) { |
| mode = drm_mode_duplicate(dev, native_mode); |
| + if (!mode) |
| + return NULL; |
| + |
| mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
| drm_mode_set_name(mode); |
| |
| @@ -401,6 +404,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder) |
| * simpler. |
| */ |
| mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); |
| + if (!mode) |
| + return NULL; |
| + |
| mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
| DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); |
| } |
| -- |
| 2.34.1 |
| |