Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vt: resize saved unicode buffer on alt screen exit after resize

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>

authored by

Nicolas Pitre and committed by
Greg Kroah-Hartman
3ddbea75 40014493

+15 -9
+15 -9
drivers/tty/vt/vt.c
··· 1901 1901 unsigned int rows = min(vc->vc_saved_rows, vc->vc_rows); 1902 1902 unsigned int cols = min(vc->vc_saved_cols, vc->vc_cols); 1903 1903 u16 *src, *dest; 1904 - bool uni_lines_stale; 1905 1904 1906 1905 if (vc->vc_saved_screen == NULL) 1907 1906 return; /* Not inside an alt-screen */ ··· 1911 1912 } 1912 1913 /* 1913 1914 * If the console was resized while in the alternate screen, 1914 - * vc_saved_uni_lines was allocated for the old dimensions. 1915 - * Restoring it would cause out-of-bounds accesses. Discard it 1916 - * and let the unicode screen be lazily rebuilt. 1915 + * resize the saved unicode buffer to the current dimensions. 1916 + * On allocation failure new_uniscr is NULL, causing the old 1917 + * buffer to be freed and vc_uni_lines to be lazily rebuilt 1918 + * via vc_uniscr_check() when next needed. 1917 1919 */ 1918 - uni_lines_stale = vc->vc_saved_rows != vc->vc_rows || 1919 - vc->vc_saved_cols != vc->vc_cols; 1920 - if (uni_lines_stale) 1920 + if (vc->vc_saved_uni_lines && 1921 + (vc->vc_saved_rows != vc->vc_rows || 1922 + vc->vc_saved_cols != vc->vc_cols)) { 1923 + u32 **new_uniscr = vc_uniscr_alloc(vc->vc_cols, vc->vc_rows); 1924 + 1925 + if (new_uniscr) 1926 + vc_uniscr_copy_area(new_uniscr, vc->vc_cols, vc->vc_rows, 1927 + vc->vc_saved_uni_lines, cols, 0, rows); 1921 1928 vc_uniscr_free(vc->vc_saved_uni_lines); 1922 - else 1923 - vc_uniscr_set(vc, vc->vc_saved_uni_lines); 1929 + vc->vc_saved_uni_lines = new_uniscr; 1930 + } 1931 + vc_uniscr_set(vc, vc->vc_saved_uni_lines); 1924 1932 vc->vc_saved_uni_lines = NULL; 1925 1933 restore_cur(vc); 1926 1934 /* Update the entire screen */