summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nico@fluxnic.net>2026-03-27 23:09:47 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-04-11 14:29:53 +0200
commitcb897316291285fcdc5f9be6d526cce875447867 (patch)
tree4687ee715dbb9e067f9059fd7768fe99b9d40ac5
parent428fdf55301e6c8fa5a36b426240797b1cf86570 (diff)
vt: resize saved unicode buffer on alt screen exit after resize
commit 3ddbea7542ae529c1a88ef9a8b1ce169126211f6 upstream. Instead of discarding the saved unicode buffer when the console was resized while in the alternate screen, resize it to the current dimensions using vc_uniscr_copy_area() to preserve its content. This properly restores the unicode screen on alt screen exit rather than lazily rebuilding it from a lossy reverse glyph translation. On allocation failure the stale buffer is freed and vc_uni_lines is set to NULL so it gets lazily rebuilt via vc_uniscr_check() when next needed. Fixes: 40014493cece ("vt: discard stale unicode buffer on alt screen exit after resize") Cc: stable <stable@kernel.org> Signed-off-by: Nicolas Pitre <nico@fluxnic.net> Link: https://patch.msgid.link/3nsr334n-079q-125n-7807-n4nq818758ns@syhkavp.arg Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/vt/vt.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index c59bc3be1136..738fac2718e6 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1907,7 +1907,6 @@ static void leave_alt_screen(struct vc_data *vc)
unsigned int rows = min(vc->vc_saved_rows, vc->vc_rows);
unsigned int cols = min(vc->vc_saved_cols, vc->vc_cols);
u16 *src, *dest;
- bool uni_lines_stale;
if (vc->vc_saved_screen == NULL)
return; /* Not inside an alt-screen */
@@ -1918,16 +1917,23 @@ static void leave_alt_screen(struct vc_data *vc)
}
/*
* If the console was resized while in the alternate screen,
- * vc_saved_uni_lines was allocated for the old dimensions.
- * Restoring it would cause out-of-bounds accesses. Discard it
- * and let the unicode screen be lazily rebuilt.
+ * resize the saved unicode buffer to the current dimensions.
+ * On allocation failure new_uniscr is NULL, causing the old
+ * buffer to be freed and vc_uni_lines to be lazily rebuilt
+ * via vc_uniscr_check() when next needed.
*/
- uni_lines_stale = vc->vc_saved_rows != vc->vc_rows ||
- vc->vc_saved_cols != vc->vc_cols;
- if (uni_lines_stale)
+ if (vc->vc_saved_uni_lines &&
+ (vc->vc_saved_rows != vc->vc_rows ||
+ vc->vc_saved_cols != vc->vc_cols)) {
+ u32 **new_uniscr = vc_uniscr_alloc(vc->vc_cols, vc->vc_rows);
+
+ if (new_uniscr)
+ vc_uniscr_copy_area(new_uniscr, vc->vc_cols, vc->vc_rows,
+ vc->vc_saved_uni_lines, cols, 0, rows);
vc_uniscr_free(vc->vc_saved_uni_lines);
- else
- vc_uniscr_set(vc, vc->vc_saved_uni_lines);
+ vc->vc_saved_uni_lines = new_uniscr;
+ }
+ vc_uniscr_set(vc, vc->vc_saved_uni_lines);
vc->vc_saved_uni_lines = NULL;
restore_cur(vc);
/* Update the entire screen */