[PATCH] drm/amd/display: perform a bounds check before filling dirty rectangles

Leo Li sunpeng.li at amd.com
Wed Jun 21 22:33:43 UTC 2023



On 6/21/23 17:57, Hamza Mahfooz wrote:
> Currently, it is possible for us to access memory that we shouldn't.
> Since, we acquire (possibly dangling) pointers to dirty rectangles
> before doing a bounds check to make sure we can actually accommodate the
> number of dirty rectangles userspace has requested to fill. This issue
> is especially evident if a compositor requests both MPO and damage clips
> at the same time, in which case I have observed a soft-hang. So, to
> avoid this issue, perform the bounds check before filling a single dirty
> rectangle and WARN() about it, if it is ever attempted in
> fill_dc_dirty_rect().
> 
> Cc: stable at vger.kernel.org # 6.1+
> Fixes: 30ebe41582d1 ("drm/amd/display: add FB_DAMAGE_CLIPS support")
> Signed-off-by: Hamza Mahfooz <hamza.mahfooz at amd.com>

Reviewed-by: Leo Li <sunpeng.li at amd.com>

Thanks!

> ---
>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 ++++---------
>   1 file changed, 4 insertions(+), 9 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 64b8dcf8dbda..66bb03d503ea 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5065,11 +5065,7 @@ static inline void fill_dc_dirty_rect(struct drm_plane *plane,
>   				      s32 y, s32 width, s32 height,
>   				      int *i, bool ffu)
>   {
> -	if (*i > DC_MAX_DIRTY_RECTS)
> -		return;
> -
> -	if (*i == DC_MAX_DIRTY_RECTS)
> -		goto out;
> +	WARN_ON(*i >= DC_MAX_DIRTY_RECTS);
>   
>   	dirty_rect->x = x;
>   	dirty_rect->y = y;
> @@ -5085,7 +5081,6 @@ static inline void fill_dc_dirty_rect(struct drm_plane *plane,
>   			"[PLANE:%d] PSR SU dirty rect at (%d, %d) size (%d, %d)",
>   			plane->base.id, x, y, width, height);
>   
> -out:
>   	(*i)++;
>   }
>   
> @@ -5172,6 +5167,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
>   
>   	*dirty_regions_changed = bb_changed;
>   
> +	if ((num_clips + (bb_changed ? 2 : 0)) > DC_MAX_DIRTY_RECTS)
> +		goto ffu;
> +
>   	if (bb_changed) {
>   		fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i],
>   				   new_plane_state->crtc_x,
> @@ -5201,9 +5199,6 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
>   				   new_plane_state->crtc_h, &i, false);
>   	}
>   
> -	if (i > DC_MAX_DIRTY_RECTS)
> -		goto ffu;
> -
>   	flip_addrs->dirty_rect_count = i;
>   	return;
>   


More information about the amd-gfx mailing list