FAILED: patch "[PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE" failed to apply to 5.8-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.8-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 988d0763361bb65690d60e2bc53a6b72777040c3 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <[email protected]>
Date: Sun, 27 Sep 2020 20:46:30 +0900
Subject: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
syzbot is reporting UAF/OOB read at bit_putcs()/soft_cursor() [1][2], for vt_resizex() from ioctl(VT_RESIZEX) allows setting font height larger than actual font height calculated by con_font_set() from ioctl(PIO_FONT). Since fbcon_set_font() from con_font_set() allocates minimal amount of memory based on actual font height calculated by con_font_set(), use of vt_resizex() can cause UAF/OOB read for font data.
VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
#define VT_RESIZE 0x5609 /* set kernel's idea of screensize */ #define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */
So far we are not aware of syzbot reports caused by setting non-zero value to v_vlin parameter. But given that it is possible that nobody is using VT_RESIZEX, we can try removing support for v_clin and v_vlin parameters.
Therefore, this patch effectively makes VT_RESIZEX behave like VT_RESIZE, with emitting a message if somebody is still using v_clin and/or v_vlin parameters.
[1] https://syzkaller.appspot.com/bug?id=32577e96d88447ded2d3b76d71254fb855245837
[2] https://syzkaller.appspot.com/bug?id=6b8355d27b2b94fb5cedf4655e3a59162d9e48e3
drivers/tty/vt/vt_ioctl.c +10 -47
@@ -772,58 +772,21 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)if (copy_from_user (&v, cs,sizeof (struct vt_consize )))return -EFAULT ; -/* FIXME: Should check the copies properly */ -if (!v.v_vlin) - v.v_vlin = vc->vc_scan_lines; - -if (v.v_clin) { -int rows = v.v_vlin / v.v_clin; -if (v.v_rows != rows) { -if (v.v_rows)/* Parameters don't add up */ -return -EINVAL ; - v.v_rows = rows; - } - } - -if (v.v_vcol && v.v_ccol) { -int cols = v.v_vcol / v.v_ccol; -if (v.v_cols != cols) { -if (v.v_cols) -return -EINVAL ; - v.v_cols = cols; - } - } - -if (v.v_clin >32 ) -return -EINVAL ; +if (v.v_vlin) +pr_info_once ("\"struct vt_consize\"->v_vlin is ignored. Please report if you need this.\n" ); +if (v.v_clin) +pr_info_once ("\"struct vt_consize\"->v_clin is ignored. Please report if you need this.\n" ); +console_lock ();for (i =0 ; i <MAX_NR_CONSOLES ; i++) { -struct vc_data *vcp; + vc = vc_cons[i].d; -if (!vc_cons[i].d) -continue ; -console_lock (); - vcp = vc_cons[i].d; -if (vcp) { -int ret; -int save_scan_lines = vcp->vc_scan_lines; -int save_font_height = vcp->vc_font.height; - -if (v.v_vlin) - vcp->vc_scan_lines = v.v_vlin; -if (v.v_clin) - vcp->vc_font.height = v.v_clin; - vcp->vc_resize_user =1 ; - ret =vc_resize (vcp, v.v_cols, v.v_rows); -if (ret) { - vcp->vc_scan_lines = save_scan_lines; - vcp->vc_font.height = save_font_height; -console_unlock (); -return ret; - } +if (vc) { + vc->vc_resize_user =1 ; +vc_resize (vc, v.v_cols, v.v_rows); } -console_unlock (); } +console_unlock ();return 0 ; }