summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/vt/vt.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 83a285577708..c59bc3be1136 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1907,6 +1907,7 @@ 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 */
@@ -1915,7 +1916,18 @@ static void leave_alt_screen(struct vc_data *vc)
dest = ((u16 *)vc->vc_origin) + r * vc->vc_cols;
memcpy(dest, src, 2 * cols);
}
- vc_uniscr_set(vc, vc->vc_saved_uni_lines);
+ /*
+ * 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.
+ */
+ uni_lines_stale = vc->vc_saved_rows != vc->vc_rows ||
+ vc->vc_saved_cols != vc->vc_cols;
+ if (uni_lines_stale)
+ vc_uniscr_free(vc->vc_saved_uni_lines);
+ else
+ vc_uniscr_set(vc, vc->vc_saved_uni_lines);
vc->vc_saved_uni_lines = NULL;
restore_cur(vc);
/* Update the entire screen */