From nobody Thu Apr 2 14:14:28 2026 Received: from flow-a6-smtp.messagingengine.com (flow-a6-smtp.messagingengine.com [103.168.172.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D05BF21257F; Sat, 28 Mar 2026 03:09:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.141 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774667391; cv=none; b=f6prnUWXKjytsCzB2zx/to3rZS85ZJM/2Zedy5Joz+pE8NjQ6pv90ppj7BefMKXC7gl8TH0mVGMH4tEMR3ji6mkI6bRhDqaXktiWFROHC7BBe3oh5MMDcLc68un3SEDGXVMWbTPtwIj6vq+7Vw4Z0ANkiJ4+5zkQGmp5ZQObObo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774667391; c=relaxed/simple; bh=1n7W0VIFDGhn7IS2NMHZdTmq7VR8tBT5LJynIpC9BlY=; h=Date:From:To:cc:Subject:Message-ID:MIME-Version:Content-Type; b=Eh8A+rWVKDpYF3ViDF2X0kNXTraGBPu335N57p6bGBWKoCV3lKdWvf/PqP2tq3spG9LjyOEHwd5nDMOmz89U1QdJUnebS1U9R8C6RabDfMhUyD0XYiwCFaR/tfF5/sEivLwq7ZCMDXxVN5e1WwCBqmA7uBz/jIOqIiSVZZ7MS0c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fluxnic.net; spf=pass smtp.mailfrom=fluxnic.net; dkim=pass (2048-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b=CCdMbhQP; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=EM/OboxI; arc=none smtp.client-ip=103.168.172.141 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b="CCdMbhQP"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="EM/OboxI" Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailflow.phl.internal (Postfix) with ESMTP id 1689C1380ABE; Fri, 27 Mar 2026 23:09:49 -0400 (EDT) Received: from phl-frontend-02 ([10.202.2.161]) by phl-compute-02.internal (MEProxy); Fri, 27 Mar 2026 23:09:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fluxnic.net; h= cc:cc:content-type:content-type:date:date:from:from:in-reply-to :message-id:mime-version:reply-to:subject:subject:to:to; s=fm2; t=1774667389; x=1774674589; bh=PwA/MmsLbOk1QIbLSYIDIq+umf8LeZ5d al0SSem/TDk=; b=CCdMbhQPr9dC2af+wXABIOQZwC23DUCgq6hf4/qtiNoq6dYW H4c8Bqg2/4EMVS5LNLLVM/bu/9G3K41FatHWNL7Vi52Ni4t6z1J1pjjzEtvWoDZV rHLQHfG92Mru7psdwj/tOsOCsIdF+ZjkqYn036Ujvq0j4jiLpblBq7FbSX5hzJ7V xJTnLCQQ0wyInTL0/3s3Ln/sXeQq6eO51rYcMoH2quSGOCU9QAojRARl7oNPBnMt DtP4xJFjXE35LDiwFPukiqvIMw1HsO//x2IHyq2L/akCxZIGv4dDUdZdBFDa7nHT R+YefZsK5ByiMB5726zqo3gjSGAQW3ry6GpJIA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:message-id :mime-version:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1774667389; x= 1774674589; bh=PwA/MmsLbOk1QIbLSYIDIq+umf8LeZ5dal0SSem/TDk=; b=E M/OboxIz/g2Kz3eTEhxM67nr5F75vO9dTLDIGadl7feCCFWs3GNhp7GFt29CKxbx 0WdT9AgMHeyxfFNDrW9k/waFgOhXNHhD4E/ChaQ1QAz9MXczItMPe8W4Ed8K72oB Z9rM78sDh6o8m09gQytK6js3L4MqEPB2HUWV72woWGCVf6drW1UQn+yksAOC9t30 bbs2Hv7s+zt/f29hqRXF+SQ7bC0JOXvOJoMOVzpRWdSzX/pB5mqLM0mxLc3tk9iM F8awiePGoliwq0TsPo5jkDM8Smj/ikPvm2va6MVdurROQHJ8GGSGq6d1o/377500 f/drb7lZmNxNczVoze7Cw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgdeffedvtdegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmneetug hnkfguqdgfufdqffettdelucdlfedttddmnecujfgurhepfffhvfevuffkgggtsehttder tddttddvnecuhfhrohhmpefpihgtohhlrghsucfrihhtrhgvuceonhhitghosehflhhugi hnihgtrdhnvghtqeenucggtffrrghtthgvrhhnpeeigfeiteevgefgtdehhfegvedvvdfh tedugeettdekveegteeifefgveeigeetvdenucffohhmrghinhepkhgvrhhnvghlrdhorh hgnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepnhhi tghosehflhhugihnihgtrdhnvghtpdhnsggprhgtphhtthhopeefpdhmohguvgepshhmth hpohhuthdprhgtphhtthhopehgrhgvghhkhheslhhinhhugihfohhunhgurghtihhonhdr ohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlh drohhrghdprhgtphhtthhopehlihhnuhigqdhsvghrihgrlhesvhhgvghrrdhkvghrnhgv lhdrohhrgh X-ME-Proxy: Feedback-ID: i58514971:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 27 Mar 2026 23:09:48 -0400 (EDT) Received: from xanadu (xanadu.lan [192.168.1.120]) by yoda.fluxnic.net (Postfix) with ESMTPSA id 1241415B1E3D; Fri, 27 Mar 2026 23:09:48 -0400 (EDT) Date: Fri, 27 Mar 2026 23:09:47 -0400 (EDT) From: Nicolas Pitre To: Greg Kroah-Hartman cc: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] vt: resize saved unicode buffer on alt screen exit after resize Message-ID: <3nsr334n-079q-125n-7807-n4nq818758ns@syhkavp.arg> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Nicolas Pitre --- Liav Mordouch identified and fixed a bug of mine where the saved unicode=20 buffer would be blindly restored with stale dimensions after a console=20 resize during the alternate screen, causing out-of-bounds accesses: https://lore.kernel.org/r/20260327170204.29706-1-liavmordouch@gmail.com His fix correctly discards the stale buffer and lets it be lazily=20 rebuilt. I don't want to simply replace his patch as he deserves credits=20 for investigating the bug and providing a good fix. This patch, which goes on top, improves on that by resizing the saved unicode buffer to the current dimensions instead of discarding it. This preserves the original unicode screen content rather than relying on a lossy reverse glyph translation to reconstruct it. It would be nice to have this in before v7.0 is released. drivers/tty/vt/vt.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 99f15b3e9544..b4b19157f05c 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1901,7 +1901,6 @@ static void leave_alt_screen(struct vc_data *vc) unsigned int rows =3D min(vc->vc_saved_rows, vc->vc_rows); unsigned int cols =3D min(vc->vc_saved_cols, vc->vc_cols); u16 *src, *dest; - bool uni_lines_stale; =20 if (vc->vc_saved_screen =3D=3D NULL) return; /* Not inside an alt-screen */ @@ -1912,16 +1911,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 =3D vc->vc_saved_rows !=3D vc->vc_rows || - vc->vc_saved_cols !=3D vc->vc_cols; - if (uni_lines_stale) + if (vc->vc_saved_uni_lines && + (vc->vc_saved_rows !=3D vc->vc_rows || + vc->vc_saved_cols !=3D vc->vc_cols)) { + u32 **new_uniscr =3D 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 =3D new_uniscr; + } + vc_uniscr_set(vc, vc->vc_saved_uni_lines); vc->vc_saved_uni_lines =3D NULL; restore_cur(vc); /* Update the entire screen */ --=20 2.53.0