mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-08-26 22:23:12 -04:00
ui/vnc: fix out-of-bounds write in lossy refresh dirty marking
vnc_refresh_lossy_rect() marks a full VNC_STAT_RECT (64) rows of the dirty bitmap when refreshing a lossy tile. When the display height is not a multiple of VNC_STAT_RECT, the last tile row is a partial tile and the loop writes past the end of vs->dirty[VNC_MAX_HEIGHT]. For example, with a 2160-pixel-high display (VNC_MAX_HEIGHT), the last stat tile starts at y=2112. The unconditional 64-row loop writes rows 2112..2175, overflowing 16 rows (640 bytes) past the dirty bitmap into subsequent VncState fields. Fix by passing the effective display height into vnc_refresh_lossy_rect() and clamping the inner loop. Fixes: CVE-2026-61475 Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3935 Reported-by: "Vulnerability Report" <vr@darknavy.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
53f0d87db7
commit
e650e4fe0f
1 changed files with 4 additions and 4 deletions
8
ui/vnc.c
8
ui/vnc.c
|
|
@ -3000,18 +3000,18 @@ void vnc_sent_lossy_rect(VncWorker *worker, int x, int y, int w, int h)
|
|||
}
|
||||
}
|
||||
|
||||
static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
|
||||
static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y,
|
||||
int height)
|
||||
{
|
||||
VncState *vs;
|
||||
int sty = y / VNC_STAT_RECT;
|
||||
int stx = x / VNC_STAT_RECT;
|
||||
int has_dirty = 0;
|
||||
int height = MIN(pixman_image_get_height(vd->guest.fb),
|
||||
pixman_image_get_height(vd->server));
|
||||
int rows;
|
||||
|
||||
y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
|
||||
x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
|
||||
rows = MIN(VNC_STAT_RECT, height - y);
|
||||
|
||||
rows = MIN(VNC_STAT_RECT, height - y);
|
||||
if (rows <= 0) {
|
||||
|
|
@ -3083,7 +3083,7 @@ static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
|
|||
|
||||
if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
|
||||
rect->freq = 0;
|
||||
has_dirty += vnc_refresh_lossy_rect(vd, x, y);
|
||||
has_dirty += vnc_refresh_lossy_rect(vd, x, y, height);
|
||||
memset(rect->times, 0, sizeof (rect->times));
|
||||
continue ;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue