Skip to content

Commit d58fb94

Browse files
effective-lightgregkh
authored andcommitted
drm/amd/display: perform a bounds check before filling dirty rectangles
commit af22d6a upstream. 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: [email protected] # 6.1+ Fixes: 30ebe41 ("drm/amd/display: add FB_DAMAGE_CLIPS support") Reviewed-by: Leo Li <[email protected]> Signed-off-by: Hamza Mahfooz <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 0441c44 commit d58fb94

File tree

1 file changed

+4
-9
lines changed

1 file changed

+4
-9
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4953,11 +4953,7 @@ static inline void fill_dc_dirty_rect(struct drm_plane *plane,
49534953
int32_t y, int32_t width, int32_t height,
49544954
int *i, bool ffu)
49554955
{
4956-
if (*i > DC_MAX_DIRTY_RECTS)
4957-
return;
4958-
4959-
if (*i == DC_MAX_DIRTY_RECTS)
4960-
goto out;
4956+
WARN_ON(*i >= DC_MAX_DIRTY_RECTS);
49614957

49624958
dirty_rect->x = x;
49634959
dirty_rect->y = y;
@@ -4973,7 +4969,6 @@ static inline void fill_dc_dirty_rect(struct drm_plane *plane,
49734969
"[PLANE:%d] PSR SU dirty rect at (%d, %d) size (%d, %d)",
49744970
plane->base.id, x, y, width, height);
49754971

4976-
out:
49774972
(*i)++;
49784973
}
49794974

@@ -5055,6 +5050,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
50555050
new_plane_state->plane->base.id,
50565051
bb_changed, fb_changed, num_clips);
50575052

5053+
if ((num_clips + (bb_changed ? 2 : 0)) > DC_MAX_DIRTY_RECTS)
5054+
goto ffu;
5055+
50585056
if (bb_changed) {
50595057
fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i],
50605058
new_plane_state->crtc_x,
@@ -5084,9 +5082,6 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
50845082
new_plane_state->crtc_h, &i, false);
50855083
}
50865084

5087-
if (i > DC_MAX_DIRTY_RECTS)
5088-
goto ffu;
5089-
50905085
flip_addrs->dirty_rect_count = i;
50915086
return;
50925087

0 commit comments

Comments
 (0)