]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Mar 2020 19:23:46 +0000 (20:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Mar 2020 19:23:46 +0000 (20:23 +0100)
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

queue-4.9/cifs-don-t-leak-eagain-for-stat-during-reconnect.patch [new file with mode: 0644]
queue-4.9/fat-fix-uninit-memory-access-for-partial-initialized-inode.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/tty-serial-mvebu-uart-fix-a-wrong-return.patch [new file with mode: 0644]
queue-4.9/usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch [new file with mode: 0644]
queue-4.9/usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch [new file with mode: 0644]
queue-4.9/usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch [new file with mode: 0644]
queue-4.9/usb-storage-add-quirk-for-samsung-fit-flash.patch [new file with mode: 0644]
queue-4.9/vgacon-fix-a-uaf-in-vgacon_invert_region.patch [new file with mode: 0644]
queue-4.9/vt-selection-close-sel_buffer-race.patch [new file with mode: 0644]
queue-4.9/vt-selection-push-console-lock-down.patch [new file with mode: 0644]

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 (file)
index 0000000..48b8dda
--- /dev/null
@@ -0,0 +1,61 @@
+From fc513fac56e1b626ae48a74d7551d9c35c50129e Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+Date: Wed, 19 Feb 2020 06:01:03 +1000
+Subject: cifs: don't leak -EAGAIN for stat() during reconnect
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+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 <lsahlber@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+CC: Stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..7bc8767
--- /dev/null
@@ -0,0 +1,74 @@
+From bc87302a093f0eab45cd4e250c2021299f712ec6 Mon Sep 17 00:00:00 2001
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Date: Thu, 5 Mar 2020 22:28:36 -0800
+Subject: fat: fix uninit-memory access for partial initialized inode
+
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+
+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 <akpm@linux-foundation.org>
+Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Cc: <stable@vger.kernel.org>
+Link: http://lkml.kernel.org/r/871rqnreqx.fsf@mail.parknet.co.jp
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
index 4924726cc4bc273964002765a4505907b0c2a53f..dee557282776667044678f984e1187f348eb7c61 100644 (file)
@@ -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 (file)
index 0000000..2fbcdc9
--- /dev/null
@@ -0,0 +1,34 @@
+From 4a3e208474204e879d22a310b244cb2f39e5b1f8 Mon Sep 17 00:00:00 2001
+From: tangbin <tangbin@cmss.chinamobile.com>
+Date: Thu, 5 Mar 2020 09:38:23 +0800
+Subject: tty:serial:mvebu-uart:fix a wrong return
+
+From: tangbin <tangbin@cmss.chinamobile.com>
+
+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 <tangbin@cmss.chinamobile.com>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20200305013823.20976-1-tangbin@cmss.chinamobile.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1e6e86f
--- /dev/null
@@ -0,0 +1,57 @@
+From 60e3f6e4ac5b0fda43dad01c32e09409ec710045 Mon Sep 17 00:00:00 2001
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+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 <erosca@de.adit-jv.com>
+
+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 <stern@rowland.harvard.edu>
+Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200226175036.14946-2-erosca@de.adit-jv.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..759e6cd
--- /dev/null
@@ -0,0 +1,62 @@
+From 1f8b39bc99a31759e97a0428a5c3f64802c1e61d Mon Sep 17 00:00:00 2001
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+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 <erosca@de.adit-jv.com>
+
+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 <stern@rowland.harvard.edu>
+Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200226175036.14946-3-erosca@de.adit-jv.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a5c9a9f
--- /dev/null
@@ -0,0 +1,34 @@
+From b96ed52d781a2026d0c0daa5787c6f3d45415862 Mon Sep 17 00:00:00 2001
+From: Dan Lazewatsky <dlaz@chromium.org>
+Date: Wed, 26 Feb 2020 14:34:38 +0000
+Subject: usb: quirks: add NO_LPM quirk for Logitech Screen Share
+
+From: Dan Lazewatsky <dlaz@chromium.org>
+
+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 <dlaz@chromium.org>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
+Link: https://lore.kernel.org/r/20200226143438.1445-1-gustavo.padovan@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1fe5cb7
--- /dev/null
@@ -0,0 +1,45 @@
+From 86d92f5465958752481269348d474414dccb1552 Mon Sep 17 00:00:00 2001
+From: Jim Lin <jilin@nvidia.com>
+Date: Mon, 2 Mar 2020 22:21:35 +0800
+Subject: usb: storage: Add quirk for Samsung Fit flash
+
+From: Jim Lin <jilin@nvidia.com>
+
+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 <jilin@nvidia.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/1583158895-31342-1-git-send-email-jilin@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a078ba0
--- /dev/null
@@ -0,0 +1,130 @@
+From 513dc792d6060d5ef572e43852683097a8420f56 Mon Sep 17 00:00:00 2001
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Date: Wed, 4 Mar 2020 10:24:29 +0800
+Subject: vgacon: Fix a UAF in vgacon_invert_region
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+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:
+    [<ffffffffb119f309>] dump_stack+0x1e/0x20
+    [<ffffffffb04af957>] kasan_report+0x577/0x950
+    [<ffffffffb04ae652>] __asan_load2+0x62/0x80
+    [<ffffffffb090f26d>] vgacon_invert_region+0x9d/0x110
+    [<ffffffffb0a39d95>] invert_screen+0xe5/0x470
+    [<ffffffffb0a21dcb>] set_selection+0x44b/0x12f0
+    [<ffffffffb0a3bfae>] tioclinux+0xee/0x490
+    [<ffffffffb0a1d114>] vt_ioctl+0xff4/0x2670
+    [<ffffffffb0a0089a>] tty_ioctl+0x46a/0x1a10
+    [<ffffffffb052db3d>] do_vfs_ioctl+0x5bd/0xc40
+    [<ffffffffb052e2f2>] SyS_ioctl+0x132/0x170
+    [<ffffffffb11c9b1b>] 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 <stdio.h>
+  #include <stdlib.h>
+  #include <unistd.h>
+  #include <fcntl.h>
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <sys/ioctl.h>
+  #include <linux/vt.h>
+
+  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 <hulkci@huawei.com>
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+[danvet: augment commit message to point out overflow safety]
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200304022429.37738-1-zhangxiaoxu5@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..c0f7b44
--- /dev/null
@@ -0,0 +1,155 @@
+From 07e6124a1a46b4b5a9b3cacc0c306b50da87abf5 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 10 Feb 2020 09:11:31 +0100
+Subject: vt: selection, close sel_buffer race
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+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 <jslaby@suse.cz>
+Reported-by: syzbot+59997e8d5cbdc486e6f6@syzkaller.appspotmail.com
+References: https://bugzilla.kernel.org/show_bug.cgi?id=206361
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200210081131.23572-2-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/tty.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
++#include <linux/mutex.h>
+ #include <linux/slab.h>
+ #include <linux/types.h>
+@@ -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 (file)
index 0000000..708c7e7
--- /dev/null
@@ -0,0 +1,67 @@
+From 4b70dd57a15d2f4685ac6e38056bad93e81e982f Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Fri, 28 Feb 2020 12:54:05 +0100
+Subject: vt: selection, push console lock down
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+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 <jslaby@suse.cz>
+Fixes: 07e6124a1a46 ("vt: selection, close sel_buffer race")
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200228115406.5735-1-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);