[PATCH] drm/amd/display: Add null check for 'afb' in amdgpu_dm_update_cursor

Harry Wentland harry.wentland at amd.com
Wed Jun 5 15:30:40 UTC 2024



On 2024-06-05 10:53, Srinivasan Shanmugam wrote:
> This commit adds a null check for the 'afb' variable in the
> amdgpu_dm_update_cursor function. Previously, 'afb' was assumed to be
> null at line 8388, but was used later in the code without a null check.
> This could potentially lead to a null pointer dereference.
> 
> Fixes the below:
> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:8433 amdgpu_dm_update_cursor()
> 	error: we previously assumed 'afb' could be null (see line 8388)
> 
> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c
>     8379 static void amdgpu_dm_update_cursor(struct drm_plane *plane,
>     8380                                     struct drm_plane_state *old_plane_state,
>     8381                                     struct dc_stream_update *update)
>     8382 {
>     8383         struct amdgpu_device *adev = drm_to_adev(plane->dev);
>     8384         struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb);
>     8385         struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc;
>                                          ^^^^^
> 
>     8386         struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
>     8387         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
>     8388         uint64_t address = afb ? afb->address : 0;
>                                     ^^^^^ Checks for NULL
> 
>     8389         struct dc_cursor_position position = {0};
>     8390         struct dc_cursor_attributes attributes;
>     8391         int ret;
>     8392
>     8393         if (!plane->state->fb && !old_plane_state->fb)
>     8394                 return;
>     8395
>     8396         drm_dbg_atomic(plane->dev, "crtc_id=%d with size %d to %d\n",
>     8397                        amdgpu_crtc->crtc_id, plane->state->crtc_w,
>     8398                        plane->state->crtc_h);
>     8399
>     8400         ret = amdgpu_dm_plane_get_cursor_position(plane, crtc, &position);
>     8401         if (ret)
>     8402                 return;
>     8403
>     8404         if (!position.enable) {
>     8405                 /* turn off cursor */
>     8406                 if (crtc_state && crtc_state->stream) {
>     8407                         dc_stream_set_cursor_position(crtc_state->stream,
>     8408                                                       &position);
>     8409                         update->cursor_position = &crtc_state->stream->cursor_position;
>     8410                 }
>     8411                 return;
>     8412         }
>     8413
>     8414         amdgpu_crtc->cursor_width = plane->state->crtc_w;
>     8415         amdgpu_crtc->cursor_height = plane->state->crtc_h;
>     8416
>     8417         memset(&attributes, 0, sizeof(attributes));
>     8418         attributes.address.high_part = upper_32_bits(address);
>     8419         attributes.address.low_part  = lower_32_bits(address);
>     8420         attributes.width             = plane->state->crtc_w;
>     8421         attributes.height            = plane->state->crtc_h;
>     8422         attributes.color_format      = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA;
>     8423         attributes.rotation_angle    = 0;
>     8424         attributes.attribute_flags.value = 0;
>     8425
>     8426         /* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM
>     8427          * legacy gamma setup.
>     8428          */
>     8429         if (crtc_state->cm_is_degamma_srgb &&
>     8430             adev->dm.dc->caps.color.dpp.gamma_corr)
>     8431                 attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1;
>     8432
> --> 8433         attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
>                                     ^^^^^                  ^^^^^
> Unchecked dereferences
> 
>     8434
>     8435         if (crtc_state->stream) {
>     8436                 if (!dc_stream_set_cursor_attributes(crtc_state->stream,
>     8437                                                      &attributes))
>     8438                         DRM_ERROR("DC failed to set cursor attributes\n");
>     8439
>     8440                 update->cursor_attributes = &crtc_state->stream->cursor_attributes;
>     8441
>     8442                 if (!dc_stream_set_cursor_position(crtc_state->stream,
>     8443                                                    &position))
>     8444                         DRM_ERROR("DC failed to set cursor position\n");
>     8445
>     8446                 update->cursor_position = &crtc_state->stream->cursor_position;
>     8447         }
>     8448 }
> 
> Fixes: 66eba12a5482 ("drm/amd/display: Do cursor programming with rest of pipe")
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Cc: Tom Chung <chiahsuan.chung at amd.com>
> Cc: Rodrigo Siqueira <Rodrigo.Siqueira at amd.com>
> Cc: Roman Li <roman.li at amd.com>
> Cc: Hersen Wu <hersenxs.wu at amd.com>
> Cc: Alex Hung <alex.hung at amd.com>
> Cc: Aurabindo Pillai <aurabindo.pillai at amd.com>
> Cc: Harry Wentland <harry.wentland at amd.com>
> Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam at amd.com>

This code comes from amdgpu_dm_plane_handle_cursor_update. Would be
good to fix the same problem in that function as well.

Reviewed-by: Harry Wentland <harry.wentland at amd.com>

Harry

> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c    | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 6196de6cebbf..6d468badb669 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -8637,14 +8637,22 @@ static void amdgpu_dm_update_cursor(struct drm_plane *plane,
>  {
>  	struct amdgpu_device *adev = drm_to_adev(plane->dev);
>  	struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb);
> -	struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc;
> -	struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
> -	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
> -	uint64_t address = afb ? afb->address : 0;
> +	struct drm_crtc *crtc;
> +	struct dm_crtc_state *crtc_state;
> +	struct amdgpu_crtc *amdgpu_crtc;
> +	u64 address;
>  	struct dc_cursor_position position = {0};
>  	struct dc_cursor_attributes attributes;
>  	int ret;
>  
> +	if (!afb)
> +		return;
> +
> +	crtc = plane->state->crtc ? plane->state->crtc : old_plane_state->crtc;
> +	crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
> +	amdgpu_crtc = to_amdgpu_crtc(crtc);
> +	address = afb->address;
> +
>  	if (!plane->state->fb && !old_plane_state->fb)
>  		return;
>  



More information about the amd-gfx mailing list