From fb976abad04be7e43d571b87ad253095ccf4ef41 Mon Sep 17 00:00:00 2001 From: John Studnicka Date: Mon, 26 Jan 2026 00:31:32 -0700 Subject: [PATCH] modesetting: Clamp image dims to avoid OOB reads Signed-off-by: John Studnicka --- .../drivers/video/modesetting/drmmode_display.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/drivers/video/modesetting/drmmode_display.c b/hw/xfree86/drivers/video/modesetting/drmmode_display.c index 9ff5408d1..88c78c841 100644 --- a/hw/xfree86/drivers/video/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/video/modesetting/drmmode_display.c @@ -1963,9 +1963,10 @@ drmmode_paint_cursor(struct dumb_bo *cursor_bo, int cursor_pitch, int cursor_wid (drmmode_crtc->cursor_glyph_width == 0 && drmmode_crtc->cursor_glyph_height == 0) || - /* Sanity check so we don't read from the image out of bounds */ - (drmmode_crtc->cursor_glyph_width > image_width || - drmmode_crtc->cursor_glyph_height > image_height) || + /* If cached glyph dimensions exceed the current crop window, force a full clear */ + (src_x < 0 || src_y < 0 || + drmmode_crtc->cursor_glyph_width > image_width - src_x || + drmmode_crtc->cursor_glyph_height > image_height - src_y) || /* If the pitch changed, the memory layout of the cursor data changed, so the buffer is dirty */ /* See: https://github.com/X11Libre/xserver/pull/1234 */ @@ -1976,7 +1977,7 @@ drmmode_paint_cursor(struct dumb_bo *cursor_bo, int cursor_pitch, int cursor_wid ) { memset(cursor, 0, cursor_bo->size); - /* Since we already cleared the buffer, no need to clear it again bellow */ + /* Since we already cleared the buffer, no need to clear it again below */ drmmode_crtc->cursor_glyph_width = 0; drmmode_crtc->cursor_glyph_height = 0; } @@ -1988,6 +1989,12 @@ drmmode_paint_cursor(struct dumb_bo *cursor_bo, int cursor_pitch, int cursor_wid width_todo = MAX(drmmode_crtc->cursor_glyph_width, glyph_width); height_todo = MAX(drmmode_crtc->cursor_glyph_height, glyph_height); + /* Clamp to the source image bounds to avoid OOB reads. */ + src_x = MIN(MAX(src_x, 0), image_width); + src_y = MIN(MAX(src_y, 0), image_height); + width_todo = MIN(width_todo, image_width - src_x); + height_todo = MIN(height_todo, image_height - src_y); + /* remember the size of the current cursor glyph */ drmmode_crtc->cursor_glyph_width = glyph_width; drmmode_crtc->cursor_glyph_height = glyph_height;