mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 07:04:24 +00:00
drm/amd/display: perform a bounds check before filling dirty rectangles
commitaf22d6a869
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: stable@vger.kernel.org # 6.1+ Fixes:30ebe41582
("drm/amd/display: add FB_DAMAGE_CLIPS support") Reviewed-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0441c44154
commit
d58fb94f24
1 changed files with 4 additions and 9 deletions
|
@ -4953,11 +4953,7 @@ static inline void fill_dc_dirty_rect(struct drm_plane *plane,
|
|||
int32_t y, int32_t width, int32_t 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;
|
||||
|
@ -4973,7 +4969,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)++;
|
||||
}
|
||||
|
||||
|
@ -5055,6 +5050,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
|
|||
new_plane_state->plane->base.id,
|
||||
bb_changed, fb_changed, num_clips);
|
||||
|
||||
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,
|
||||
|
@ -5084,9 +5082,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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue