From: Greg Kroah-Hartman Date: Mon, 9 Mar 2020 19:23:46 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.216~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cf3c7c2c8250e01f8b7ba6a9be556714202dca79;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: cifs-don-t-leak-eagain-for-stat-during-reconnect.patch fat-fix-uninit-memory-access-for-partial-initialized-inode.patch tty-serial-mvebu-uart-fix-a-wrong-return.patch usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch usb-storage-add-quirk-for-samsung-fit-flash.patch vgacon-fix-a-uaf-in-vgacon_invert_region.patch vt-selection-close-sel_buffer-race.patch vt-selection-push-console-lock-down.patch --- diff --git a/queue-4.9/cifs-don-t-leak-eagain-for-stat-during-reconnect.patch b/queue-4.9/cifs-don-t-leak-eagain-for-stat-during-reconnect.patch new file mode 100644 index 00000000000..48b8dda9164 --- /dev/null +++ b/queue-4.9/cifs-don-t-leak-eagain-for-stat-during-reconnect.patch @@ -0,0 +1,61 @@ +From fc513fac56e1b626ae48a74d7551d9c35c50129e Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Wed, 19 Feb 2020 06:01:03 +1000 +Subject: cifs: don't leak -EAGAIN for stat() during reconnect + +From: Ronnie Sahlberg + +commit fc513fac56e1b626ae48a74d7551d9c35c50129e upstream. + +If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an +error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected +it is possible we will leak -EAGAIN back to the application even for +system calls such as stat() where this is not a valid error. + +Fix this by re-trying the operation from within cifs_revalidate_dentry_attr() +if cifs_get_inode_info*() returns -EAGAIN. + +This fixes stat() and possibly also other system calls that uses +cifs_revalidate_dentry*(). + +Signed-off-by: Ronnie Sahlberg +Signed-off-by: Steve French +Reviewed-by: Pavel Shilovsky +Reviewed-by: Aurelien Aptel +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/inode.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -1990,6 +1990,7 @@ int cifs_revalidate_dentry_attr(struct d + struct inode *inode = d_inode(dentry); + struct super_block *sb = dentry->d_sb; + char *full_path = NULL; ++ int count = 0; + + if (inode == NULL) + return -ENOENT; +@@ -2011,15 +2012,18 @@ int cifs_revalidate_dentry_attr(struct d + full_path, inode, inode->i_count.counter, + dentry, cifs_get_time(dentry), jiffies); + ++again: + if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); + else + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, + xid, NULL); +- ++ if (rc == -EAGAIN && count++ < 10) ++ goto again; + out: + kfree(full_path); + free_xid(xid); ++ + return rc; + } + diff --git a/queue-4.9/fat-fix-uninit-memory-access-for-partial-initialized-inode.patch b/queue-4.9/fat-fix-uninit-memory-access-for-partial-initialized-inode.patch new file mode 100644 index 00000000000..7bc876719b2 --- /dev/null +++ b/queue-4.9/fat-fix-uninit-memory-access-for-partial-initialized-inode.patch @@ -0,0 +1,74 @@ +From bc87302a093f0eab45cd4e250c2021299f712ec6 Mon Sep 17 00:00:00 2001 +From: OGAWA Hirofumi +Date: Thu, 5 Mar 2020 22:28:36 -0800 +Subject: fat: fix uninit-memory access for partial initialized inode + +From: OGAWA Hirofumi + +commit bc87302a093f0eab45cd4e250c2021299f712ec6 upstream. + +When get an error in the middle of reading an inode, some fields in the +inode might be still not initialized. And then the evict_inode path may +access those fields via iput(). + +To fix, this makes sure that inode fields are initialized. + +Reported-by: syzbot+9d82b8de2992579da5d0@syzkaller.appspotmail.com +Signed-off-by: Andrew Morton +Signed-off-by: OGAWA Hirofumi +Cc: +Link: http://lkml.kernel.org/r/871rqnreqx.fsf@mail.parknet.co.jp +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fat/inode.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +--- a/fs/fat/inode.c ++++ b/fs/fat/inode.c +@@ -736,6 +736,13 @@ static struct inode *fat_alloc_inode(str + return NULL; + + init_rwsem(&ei->truncate_lock); ++ /* Zeroing to allow iput() even if partial initialized inode. */ ++ ei->mmu_private = 0; ++ ei->i_start = 0; ++ ei->i_logstart = 0; ++ ei->i_attrs = 0; ++ ei->i_pos = 0; ++ + return &ei->vfs_inode; + } + +@@ -1366,16 +1373,6 @@ out: + return 0; + } + +-static void fat_dummy_inode_init(struct inode *inode) +-{ +- /* Initialize this dummy inode to work as no-op. */ +- MSDOS_I(inode)->mmu_private = 0; +- MSDOS_I(inode)->i_start = 0; +- MSDOS_I(inode)->i_logstart = 0; +- MSDOS_I(inode)->i_attrs = 0; +- MSDOS_I(inode)->i_pos = 0; +-} +- + static int fat_read_root(struct inode *inode) + { + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); +@@ -1820,13 +1817,11 @@ int fat_fill_super(struct super_block *s + fat_inode = new_inode(sb); + if (!fat_inode) + goto out_fail; +- fat_dummy_inode_init(fat_inode); + sbi->fat_inode = fat_inode; + + fsinfo_inode = new_inode(sb); + if (!fsinfo_inode) + goto out_fail; +- fat_dummy_inode_init(fsinfo_inode); + fsinfo_inode->i_ino = MSDOS_FSINFO_INO; + sbi->fsinfo_inode = fsinfo_inode; + insert_inode_hash(fsinfo_inode); diff --git a/queue-4.9/series b/queue-4.9/series index 4924726cc4b..dee55728277 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -60,3 +60,13 @@ net-ks8851-ml-fix-16-bit-io-operation.patch watchdog-da9062-do-not-ping-the-hw-during-stop.patch s390-cio-cio_ignore_proc_seq_next-should-increase-po.patch x86-boot-compressed-don-t-declare-__force_order-in-k.patch +cifs-don-t-leak-eagain-for-stat-during-reconnect.patch +usb-storage-add-quirk-for-samsung-fit-flash.patch +usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch +usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch +usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch +vgacon-fix-a-uaf-in-vgacon_invert_region.patch +fat-fix-uninit-memory-access-for-partial-initialized-inode.patch +tty-serial-mvebu-uart-fix-a-wrong-return.patch +vt-selection-close-sel_buffer-race.patch +vt-selection-push-console-lock-down.patch diff --git a/queue-4.9/tty-serial-mvebu-uart-fix-a-wrong-return.patch b/queue-4.9/tty-serial-mvebu-uart-fix-a-wrong-return.patch new file mode 100644 index 00000000000..2fbcdc909a8 --- /dev/null +++ b/queue-4.9/tty-serial-mvebu-uart-fix-a-wrong-return.patch @@ -0,0 +1,34 @@ +From 4a3e208474204e879d22a310b244cb2f39e5b1f8 Mon Sep 17 00:00:00 2001 +From: tangbin +Date: Thu, 5 Mar 2020 09:38:23 +0800 +Subject: tty:serial:mvebu-uart:fix a wrong return + +From: tangbin + +commit 4a3e208474204e879d22a310b244cb2f39e5b1f8 upstream. + +in this place, the function should return a +negative value and the PTR_ERR already returns +a negative,so return -PTR_ERR() is wrong. + +Signed-off-by: tangbin +Cc: stable +Acked-by: Jiri Slaby +Link: https://lore.kernel.org/r/20200305013823.20976-1-tangbin@cmss.chinamobile.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/mvebu-uart.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/mvebu-uart.c ++++ b/drivers/tty/serial/mvebu-uart.c +@@ -581,7 +581,7 @@ static int mvebu_uart_probe(struct platf + + port->membase = devm_ioremap_resource(&pdev->dev, reg); + if (IS_ERR(port->membase)) +- return -PTR_ERR(port->membase); ++ return PTR_ERR(port->membase); + + data = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart_data), + GFP_KERNEL); diff --git a/queue-4.9/usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch b/queue-4.9/usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch new file mode 100644 index 00000000000..1e6e86f1790 --- /dev/null +++ b/queue-4.9/usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch @@ -0,0 +1,57 @@ +From 60e3f6e4ac5b0fda43dad01c32e09409ec710045 Mon Sep 17 00:00:00 2001 +From: Eugeniu Rosca +Date: Wed, 26 Feb 2020 18:50:35 +0100 +Subject: usb: core: hub: do error out if usb_autopm_get_interface() fails + +From: Eugeniu Rosca + +commit 60e3f6e4ac5b0fda43dad01c32e09409ec710045 upstream. + +Reviewing a fresh portion of coverity defects in USB core +(specifically CID 1458999), Alan Stern noted below in [1]: + +On Tue, Feb 25, 2020 at 02:39:23PM -0500, Alan Stern wrote: + > A revised search finds line 997 in drivers/usb/core/hub.c and lines + > 216, 269 in drivers/usb/core/port.c. (I didn't try looking in any + > other directories.) AFAICT all three of these should check the + > return value, although a error message in the kernel log probably + > isn't needed. + +Factor out the usb_remove_device() change into a standalone patch to +allow conflict-free integration on top of the earliest stable branches. + +[1] https://lore.kernel.org/lkml/Pine.LNX.4.44L0.2002251419120.1485-100000@iolanthe.rowland.org + +Fixes: 253e05724f9230 ("USB: add a "remove hardware" sysfs attribute") +Cc: stable@vger.kernel.org # v2.6.33+ +Suggested-by: Alan Stern +Signed-off-by: Eugeniu Rosca +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/20200226175036.14946-2-erosca@de.adit-jv.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -954,13 +954,17 @@ int usb_remove_device(struct usb_device + { + struct usb_hub *hub; + struct usb_interface *intf; ++ int ret; + + if (!udev->parent) /* Can't remove a root hub */ + return -EINVAL; + hub = usb_hub_to_struct_hub(udev->parent); + intf = to_usb_interface(hub->intfdev); + +- usb_autopm_get_interface(intf); ++ ret = usb_autopm_get_interface(intf); ++ if (ret < 0) ++ return ret; ++ + set_bit(udev->portnum, hub->removed_bits); + hub_port_logical_disconnect(hub, udev->portnum); + usb_autopm_put_interface(intf); diff --git a/queue-4.9/usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch b/queue-4.9/usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch new file mode 100644 index 00000000000..759e6cda26c --- /dev/null +++ b/queue-4.9/usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch @@ -0,0 +1,62 @@ +From 1f8b39bc99a31759e97a0428a5c3f64802c1e61d Mon Sep 17 00:00:00 2001 +From: Eugeniu Rosca +Date: Wed, 26 Feb 2020 18:50:36 +0100 +Subject: usb: core: port: do error out if usb_autopm_get_interface() fails + +From: Eugeniu Rosca + +commit 1f8b39bc99a31759e97a0428a5c3f64802c1e61d upstream. + +Reviewing a fresh portion of coverity defects in USB core +(specifically CID 1458999), Alan Stern noted below in [1]: + +On Tue, Feb 25, 2020 at 02:39:23PM -0500, Alan Stern wrote: + > A revised search finds line 997 in drivers/usb/core/hub.c and lines + > 216, 269 in drivers/usb/core/port.c. (I didn't try looking in any + > other directories.) AFAICT all three of these should check the + > return value, although a error message in the kernel log probably + > isn't needed. + +Factor out the usb_port_runtime_{resume,suspend}() changes into a +standalone patch to allow conflict-free porting on top of stable v3.9+. + +[1] https://lore.kernel.org/lkml/Pine.LNX.4.44L0.2002251419120.1485-100000@iolanthe.rowland.org + +Fixes: 971fcd492cebf5 ("usb: add runtime pm support for usb port device") +Cc: stable@vger.kernel.org # v3.9+ +Suggested-by: Alan Stern +Signed-off-by: Eugeniu Rosca +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/20200226175036.14946-3-erosca@de.adit-jv.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/port.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/port.c ++++ b/drivers/usb/core/port.c +@@ -179,7 +179,10 @@ static int usb_port_runtime_resume(struc + if (!port_dev->is_superspeed && peer) + pm_runtime_get_sync(&peer->dev); + +- usb_autopm_get_interface(intf); ++ retval = usb_autopm_get_interface(intf); ++ if (retval < 0) ++ return retval; ++ + retval = usb_hub_set_port_power(hdev, hub, port1, true); + msleep(hub_power_on_good_delay(hub)); + if (udev && !retval) { +@@ -232,7 +235,10 @@ static int usb_port_runtime_suspend(stru + if (usb_port_block_power_off) + return -EBUSY; + +- usb_autopm_get_interface(intf); ++ retval = usb_autopm_get_interface(intf); ++ if (retval < 0) ++ return retval; ++ + retval = usb_hub_set_port_power(hdev, hub, port1, false); + usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); + if (!port_dev->is_superspeed) diff --git a/queue-4.9/usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch b/queue-4.9/usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch new file mode 100644 index 00000000000..a5c9a9fe477 --- /dev/null +++ b/queue-4.9/usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch @@ -0,0 +1,34 @@ +From b96ed52d781a2026d0c0daa5787c6f3d45415862 Mon Sep 17 00:00:00 2001 +From: Dan Lazewatsky +Date: Wed, 26 Feb 2020 14:34:38 +0000 +Subject: usb: quirks: add NO_LPM quirk for Logitech Screen Share + +From: Dan Lazewatsky + +commit b96ed52d781a2026d0c0daa5787c6f3d45415862 upstream. + +LPM on the device appears to cause xHCI host controllers to claim +that there isn't enough bandwidth to support additional devices. + +Signed-off-by: Dan Lazewatsky +Cc: stable +Signed-off-by: Gustavo Padovan +Link: https://lore.kernel.org/r/20200226143438.1445-1-gustavo.padovan@collabora.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -86,6 +86,9 @@ static const struct usb_device_id usb_qu + /* Logitech PTZ Pro Camera */ + { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT }, + ++ /* Logitech Screen Share */ ++ { USB_DEVICE(0x046d, 0x086c), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Logitech Quickcam Fusion */ + { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, + diff --git a/queue-4.9/usb-storage-add-quirk-for-samsung-fit-flash.patch b/queue-4.9/usb-storage-add-quirk-for-samsung-fit-flash.patch new file mode 100644 index 00000000000..1fe5cb7029e --- /dev/null +++ b/queue-4.9/usb-storage-add-quirk-for-samsung-fit-flash.patch @@ -0,0 +1,45 @@ +From 86d92f5465958752481269348d474414dccb1552 Mon Sep 17 00:00:00 2001 +From: Jim Lin +Date: Mon, 2 Mar 2020 22:21:35 +0800 +Subject: usb: storage: Add quirk for Samsung Fit flash + +From: Jim Lin + +commit 86d92f5465958752481269348d474414dccb1552 upstream. + +Current driver has 240 (USB2.0) and 2048 (USB3.0) as max_sectors, +e.g., /sys/bus/scsi/devices/0:0:0:0/max_sectors + +If data access times out, driver error handling will issue a port +reset. +Sometimes Samsung Fit (090C:1000) flash disk will not respond to +later Set Address or Get Descriptor command. + +Adding this quirk to limit max_sectors to 64 sectors to avoid issue +occurring. + +Signed-off-by: Jim Lin +Acked-by: Alan Stern +Cc: stable +Link: https://lore.kernel.org/r/1583158895-31342-1-git-send-email-jilin@nvidia.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/unusual_devs.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1277,6 +1277,12 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9 + USB_SC_RBC, USB_PR_BULK, NULL, + 0 ), + ++UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100, ++ "Samsung", ++ "Flash Drive FIT", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_MAX_SECTORS_64), ++ + /* aeb */ + UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, + "Feiya", diff --git a/queue-4.9/vgacon-fix-a-uaf-in-vgacon_invert_region.patch b/queue-4.9/vgacon-fix-a-uaf-in-vgacon_invert_region.patch new file mode 100644 index 00000000000..a078ba01537 --- /dev/null +++ b/queue-4.9/vgacon-fix-a-uaf-in-vgacon_invert_region.patch @@ -0,0 +1,130 @@ +From 513dc792d6060d5ef572e43852683097a8420f56 Mon Sep 17 00:00:00 2001 +From: Zhang Xiaoxu +Date: Wed, 4 Mar 2020 10:24:29 +0800 +Subject: vgacon: Fix a UAF in vgacon_invert_region + +From: Zhang Xiaoxu + +commit 513dc792d6060d5ef572e43852683097a8420f56 upstream. + +When syzkaller tests, there is a UAF: + BUG: KASan: use after free in vgacon_invert_region+0x9d/0x110 at addr + ffff880000100000 + Read of size 2 by task syz-executor.1/16489 + page:ffffea0000004000 count:0 mapcount:-127 mapping: (null) + index:0x0 + page flags: 0xfffff00000000() + page dumped because: kasan: bad access detected + CPU: 1 PID: 16489 Comm: syz-executor.1 Not tainted + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS + rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014 + Call Trace: + [] dump_stack+0x1e/0x20 + [] kasan_report+0x577/0x950 + [] __asan_load2+0x62/0x80 + [] vgacon_invert_region+0x9d/0x110 + [] invert_screen+0xe5/0x470 + [] set_selection+0x44b/0x12f0 + [] tioclinux+0xee/0x490 + [] vt_ioctl+0xff4/0x2670 + [] tty_ioctl+0x46a/0x1a10 + [] do_vfs_ioctl+0x5bd/0xc40 + [] SyS_ioctl+0x132/0x170 + [] system_call_fastpath+0x22/0x27 + Memory state around the buggy address: + ffff8800000fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 + ffff8800000fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 + >ffff880000100000: ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff + +It can be reproduce in the linux mainline by the program: + #include + #include + #include + #include + #include + #include + #include + #include + + struct tiocl_selection { + unsigned short xs; /* X start */ + unsigned short ys; /* Y start */ + unsigned short xe; /* X end */ + unsigned short ye; /* Y end */ + unsigned short sel_mode; /* selection mode */ + }; + + #define TIOCL_SETSEL 2 + struct tiocl { + unsigned char type; + unsigned char pad; + struct tiocl_selection sel; + }; + + int main() + { + int fd = 0; + const char *dev = "/dev/char/4:1"; + + struct vt_consize v = {0}; + struct tiocl tioc = {0}; + + fd = open(dev, O_RDWR, 0); + + v.v_rows = 3346; + ioctl(fd, VT_RESIZEX, &v); + + tioc.type = TIOCL_SETSEL; + ioctl(fd, TIOCLINUX, &tioc); + + return 0; + } + +When resize the screen, update the 'vc->vc_size_row' to the new_row_size, +but when 'set_origin' in 'vgacon_set_origin', vgacon use 'vga_vram_base' +for 'vc_origin' and 'vc_visible_origin', not 'vc_screenbuf'. It maybe +smaller than 'vc_screenbuf'. When TIOCLINUX, use the new_row_size to calc +the offset, it maybe larger than the vga_vram_size in vgacon driver, then +bad access. +Also, if set an larger screenbuf firstly, then set an more larger +screenbuf, when copy old_origin to new_origin, a bad access may happen. + +So, If the screen size larger than vga_vram, resize screen should be +failed. This alse fix CVE-2020-8649 and CVE-2020-8647. + +Linus pointed out that overflow checking seems absent. We're saved by +the existing bounds checks in vc_do_resize() with rather strict +limits: + + if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW) + return -EINVAL; + +Fixes: 0aec4867dca14 ("[PATCH] SVGATextMode fix") +Reference: CVE-2020-8647 and CVE-2020-8649 +Reported-by: Hulk Robot +Signed-off-by: Zhang Xiaoxu +[danvet: augment commit message to point out overflow safety] +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20200304022429.37738-1-zhangxiaoxu5@huawei.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/console/vgacon.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -1323,6 +1323,9 @@ static int vgacon_font_get(struct vc_dat + static int vgacon_resize(struct vc_data *c, unsigned int width, + unsigned int height, unsigned int user) + { ++ if ((width << 1) * height > vga_vram_size) ++ return -EINVAL; ++ + if (width % 2 || width > screen_info.orig_video_cols || + height > (screen_info.orig_video_lines * vga_default_font_height)/ + c->vc_font.height) diff --git a/queue-4.9/vt-selection-close-sel_buffer-race.patch b/queue-4.9/vt-selection-close-sel_buffer-race.patch new file mode 100644 index 00000000000..c0f7b440c1a --- /dev/null +++ b/queue-4.9/vt-selection-close-sel_buffer-race.patch @@ -0,0 +1,155 @@ +From 07e6124a1a46b4b5a9b3cacc0c306b50da87abf5 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 10 Feb 2020 09:11:31 +0100 +Subject: vt: selection, close sel_buffer race + +From: Jiri Slaby + +commit 07e6124a1a46b4b5a9b3cacc0c306b50da87abf5 upstream. + +syzkaller reported this UAF: +BUG: KASAN: use-after-free in n_tty_receive_buf_common+0x2481/0x2940 drivers/tty/n_tty.c:1741 +Read of size 1 at addr ffff8880089e40e9 by task syz-executor.1/13184 + +CPU: 0 PID: 13184 Comm: syz-executor.1 Not tainted 5.4.7 #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 +Call Trace: +... + kasan_report+0xe/0x20 mm/kasan/common.c:634 + n_tty_receive_buf_common+0x2481/0x2940 drivers/tty/n_tty.c:1741 + tty_ldisc_receive_buf+0xac/0x190 drivers/tty/tty_buffer.c:461 + paste_selection+0x297/0x400 drivers/tty/vt/selection.c:372 + tioclinux+0x20d/0x4e0 drivers/tty/vt/vt.c:3044 + vt_ioctl+0x1bcf/0x28d0 drivers/tty/vt/vt_ioctl.c:364 + tty_ioctl+0x525/0x15a0 drivers/tty/tty_io.c:2657 + vfs_ioctl fs/ioctl.c:47 [inline] + +It is due to a race between parallel paste_selection (TIOCL_PASTESEL) +and set_selection_user (TIOCL_SETSEL) invocations. One uses sel_buffer, +while the other frees it and reallocates a new one for another +selection. Add a mutex to close this race. + +The mutex takes care properly of sel_buffer and sel_buffer_lth only. The +other selection global variables (like sel_start, sel_end, and sel_cons) +are protected only in set_selection_user. The other functions need quite +some more work to close the races of the variables there. This is going +to happen later. + +This likely fixes (I am unsure as there is no reproducer provided) bug +206361 too. It was marked as CVE-2020-8648. + +Signed-off-by: Jiri Slaby +Reported-by: syzbot+59997e8d5cbdc486e6f6@syzkaller.appspotmail.com +References: https://bugzilla.kernel.org/show_bug.cgi?id=206361 +Cc: stable +Link: https://lore.kernel.org/r/20200210081131.23572-2-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/selection.c | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +--- a/drivers/tty/vt/selection.c ++++ b/drivers/tty/vt/selection.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -40,6 +41,7 @@ static volatile int sel_start = -1; /* + static int sel_end; + static int sel_buffer_lth; + static char *sel_buffer; ++static DEFINE_MUTEX(sel_lock); + + /* clear_selection, highlight and highlight_pointer can be called + from interrupt (via scrollback/front) */ +@@ -163,7 +165,7 @@ int set_selection(const struct tiocl_sel + char *bp, *obp; + int i, ps, pe, multiplier; + u16 c; +- int mode; ++ int mode, ret = 0; + + poke_blanked_console(); + +@@ -203,6 +205,7 @@ int set_selection(const struct tiocl_sel + pe = tmp; + } + ++ mutex_lock(&sel_lock); + if (sel_cons != vc_cons[fg_console].d) { + clear_selection(); + sel_cons = vc_cons[fg_console].d; +@@ -248,9 +251,10 @@ int set_selection(const struct tiocl_sel + break; + case TIOCL_SELPOINTER: + highlight_pointer(pe); +- return 0; ++ goto unlock; + default: +- return -EINVAL; ++ ret = -EINVAL; ++ goto unlock; + } + + /* remove the pointer */ +@@ -272,7 +276,7 @@ int set_selection(const struct tiocl_sel + else if (new_sel_start == sel_start) + { + if (new_sel_end == sel_end) /* no action required */ +- return 0; ++ goto unlock; + else if (new_sel_end > sel_end) /* extend to right */ + highlight(sel_end + 2, new_sel_end); + else /* contract from right */ +@@ -299,7 +303,8 @@ int set_selection(const struct tiocl_sel + if (!bp) { + printk(KERN_WARNING "selection: kmalloc() failed\n"); + clear_selection(); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto unlock; + } + kfree(sel_buffer); + sel_buffer = bp; +@@ -324,7 +329,9 @@ int set_selection(const struct tiocl_sel + } + } + sel_buffer_lth = bp - sel_buffer; +- return 0; ++unlock: ++ mutex_unlock(&sel_lock); ++ return ret; + } + + /* Insert the contents of the selection buffer into the +@@ -353,6 +360,7 @@ int paste_selection(struct tty_struct *t + tty_buffer_lock_exclusive(&vc->port); + + add_wait_queue(&vc->paste_wait, &wait); ++ mutex_lock(&sel_lock); + while (sel_buffer && sel_buffer_lth > pasted) { + set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current)) { +@@ -360,7 +368,9 @@ int paste_selection(struct tty_struct *t + break; + } + if (tty_throttled(tty)) { ++ mutex_unlock(&sel_lock); + schedule(); ++ mutex_lock(&sel_lock); + continue; + } + __set_current_state(TASK_RUNNING); +@@ -369,6 +379,7 @@ int paste_selection(struct tty_struct *t + count); + pasted += count; + } ++ mutex_unlock(&sel_lock); + remove_wait_queue(&vc->paste_wait, &wait); + __set_current_state(TASK_RUNNING); + diff --git a/queue-4.9/vt-selection-push-console-lock-down.patch b/queue-4.9/vt-selection-push-console-lock-down.patch new file mode 100644 index 00000000000..708c7e7e575 --- /dev/null +++ b/queue-4.9/vt-selection-push-console-lock-down.patch @@ -0,0 +1,67 @@ +From 4b70dd57a15d2f4685ac6e38056bad93e81e982f Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Fri, 28 Feb 2020 12:54:05 +0100 +Subject: vt: selection, push console lock down + +From: Jiri Slaby + +commit 4b70dd57a15d2f4685ac6e38056bad93e81e982f upstream. + +We need to nest the console lock in sel_lock, so we have to push it down +a bit. Fortunately, the callers of set_selection_* just lock the console +lock around the function call. So moving it down is easy. + +In the next patch, we switch the order. + +Signed-off-by: Jiri Slaby +Fixes: 07e6124a1a46 ("vt: selection, close sel_buffer race") +Cc: stable +Link: https://lore.kernel.org/r/20200228115406.5735-1-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/selection.c | 13 ++++++++++++- + drivers/tty/vt/vt.c | 2 -- + 2 files changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/tty/vt/selection.c ++++ b/drivers/tty/vt/selection.c +@@ -158,7 +158,7 @@ static int store_utf8(u16 c, char *p) + * The entire selection process is managed under the console_lock. It's + * a lot under the lock but its hardly a performance path + */ +-int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty) ++static int __set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty) + { + struct vc_data *vc = vc_cons[fg_console].d; + int sel_mode, new_sel_start, new_sel_end, spc; +@@ -334,6 +334,17 @@ unlock: + return ret; + } + ++int set_selection(const struct tiocl_selection __user *v, struct tty_struct *tty) ++{ ++ int ret; ++ ++ console_lock(); ++ ret = __set_selection(v, tty); ++ console_unlock(); ++ ++ return ret; ++} ++ + /* Insert the contents of the selection buffer into the + * queue of the tty associated with the current console. + * Invoked by ioctl(). +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -2690,9 +2690,7 @@ int tioclinux(struct tty_struct *tty, un + switch (type) + { + case TIOCL_SETSEL: +- console_lock(); + ret = set_selection((struct tiocl_selection __user *)(p+1), tty); +- console_unlock(); + break; + case TIOCL_PASTESEL: + ret = paste_selection(tty);