In amdgpu_dm_plane_drm_plane_reset(), the old plane state is freed
before allocating a new one. If kzalloc_obj() fails, the function
returns without updating plane->state, leaving a dangling pointer
to already freed memory.
Fix this by allocating the new state first. If allocation fails,
free the old state (if present) and set plane->state to NULL to
prevent any dangling references.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 5d945cbcd4b1 ("drm/amd/display: Create a file dedicated to planes")
Signed-off-by: Evgenii Burenchev <[email protected]>
---
.../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 20 ++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index e957657b06c7..0d81cef5fdaa 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1490,20 +1490,30 @@ static void amdgpu_dm_plane_drm_plane_reset(struct
drm_plane *plane)
{
struct dm_plane_state *amdgpu_state = NULL;
- if (plane->state)
- plane->funcs->atomic_destroy_state(plane, plane->state);
-
amdgpu_state = kzalloc_obj(*amdgpu_state);
- WARN_ON(amdgpu_state == NULL);
if (!amdgpu_state)
- return;
+ goto err_alloc;
+
+ /* Old state can now be safely destroyed. The new state is already
allocated and will be assigned */
+ if (plane->state)
+ plane->funcs->atomic_destroy_state(plane, plane->state);
__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
amdgpu_state->shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
amdgpu_state->blend_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
+
+ return;
+
+err_alloc:
+ /* Allocation failed: free old state (if present) and set plane->state
to NULL */
+ if (plane->state) {
+ plane->funcs->atomic_destroy_state(plane, plane->state);
+ plane->state = NULL;
+ }
+ WARN_ON(amdgpu_state == NULL);
}
static struct drm_plane_state
*amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane)
--
2.43.0