On 6/7/26 14:53, Marc-André Lureau wrote:
vnc_refresh_lossy_rect() always marks a full VNC_STAT_RECT (64) rows
as dirty when refreshing a lossy tile. When the display height is not
a multiple of VNC_STAT_RECT (e.g. VNC_MAX_HEIGHT = 2160), the bottom
tile is partial -- the last tile at y=2112 has only 48 valid rows.
The unclamped loop writes to vs->dirty[2160..2175], past the end of
the VNC_MAX_HEIGHT-sized array.
Clamp the row count to the actual surface height so partial bottom
tiles only mark valid dirty bitmap entries.
Fixes: CVE-2026-48002
Fixes: 7d964c9d2fc6 ("vnc: refresh lossy rect after a given timeout")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3950
Reported-by: huntr bubble
Signed-off-by: Marc-Andre Lureau <[email protected]>
---
ui/vnc.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index b2b69923b75..559d3954b87 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3004,10 +3004,18 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int
x, int y)
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));
This could deserve some helper, anyway:
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
+ 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);
+ if (rows <= 0) {
+ return 0;
+ }