PATCH] vga: split text renderer geometry cache from graphics renderer

sin99xx <[email protected]>
Newsgroups org.nongnu.qemu-devel
Message-ID <CAMX0No0RNTzennt6Z7t4-zO1y=b1o2jBtz-CfdWTpV+wyq_NTw@mail.gmail.com>
vga_draw_text() and vga_draw_graphic() share last_width/last_height
but store them in different units (chars vs pixels).  A graphics
frame leaving values equal to a following text frame's char counts
makes the text resize predicate compare equal, skipping the console
resize; the glyph loop then paints out of bounds of the surface.

Commit 95687639e6 (CVE-2026-17516) fixed the graphics-path consumer
of this confusion but not the text path.  Give vga_draw_text() its
own cache fields.

Fixes: CVE-2026-77913
Cc: [email protected]
Signed-off-by: Warisjeet Singh (sin99xx) <[email protected]>
---
 hw/display/vga.c     | 10 +++++++---
 hw/display/vga_int.h |  3 ++-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1241,7 +1241,7 @@
         return;
     }

-    if (width != s->last_width || height != s->last_height ||
+    if (width != s->last_text_width || height != s->last_text_height ||
         cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
         s->last_scr_width = width * cw;
         s->last_scr_height = height * cheight;
@@ -1249,8 +1249,8 @@
         surface = qemu_console_surface(s->con);
         qemu_console_text_resize(s->con, width, height);
         s->last_depth = 0;
-        s->last_width = width;
-        s->last_height = height;
+        s->last_text_width = width;
+        s->last_text_height = height;
         s->last_ch = cheight;
         s->last_cw = cw;
         full_update = 1;
@@ -1845,6 +1845,8 @@

     s->last_width = -1;
     s->last_height = -1;
+    s->last_text_width = -1;
+    s->last_text_height = -1;
 }

 void vga_common_reset(VGACommonState *s)
@@ -1887,6 +1889,8 @@
     s->last_ch = 0;
     s->last_width = 0;
     s->last_height = 0;
+    s->last_text_width = 0;
+    s->last_text_height = 0;
     s->last_scr_width = 0;
     s->last_scr_height = 0;
     s->cursor_start = 0;
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -122,7 +122,8 @@
     uint32_t plane_updated;
     uint32_t last_line_offset;
     uint8_t last_cw, last_ch;
-    uint32_t last_width, last_height; /* in chars or pixels */
+    uint32_t last_width, last_height; /* in pixels (graphics renderer) */
+    uint32_t last_text_width, last_text_height; /* in chars (text renderer) */
     uint32_t last_scr_width, last_scr_height; /* in pixels */
     uint32_t last_depth; /* in bits */
     bool last_byteswap;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.