From: Greg Kroah-Hartman Date: Mon, 9 Mar 2020 19:22:24 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.216~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=16c5f56cf174fc351a200d2725577498ffc63e73;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: arm-dts-dra76x-fix-mmc3-max-frequency.patch arm64-dts-socfpga-agilex-fix-gmac-compatible.patch btrfs-fix-raid-direct-i-o-reads-with-alternate-csums.patch fat-fix-uninit-memory-access-for-partial-initialized-inode.patch locks-fix-a-potential-use-after-free-problem-when-wakeup-a-waiter.patch mm-fix-possible-pmd-dirty-bit-lost-in-set_pmd_migration_entry.patch mm-hotplug-fix-page-online-with-debug_pagealloc-compiled-but-not-enabled.patch mm-numa-fix-bad-pmd-by-atomically-check-for-pmd_trans_huge-when-marking-page-tables-prot_numa.patch revert-software-node-simplify-software_node_release-function.patch serial-8250_exar-add-support-for-acces-cards.patch tty-serial-fsl_lpuart-free-ids-allocated-by-ida.patch tty-serial-mvebu-uart-fix-a-wrong-return.patch usb-cdns3-gadget-link-trb-should-point-to-next-request.patch usb-cdns3-gadget-toggle-cycle-bit-before-reset-endpoint.patch usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch usb-core-hub-fix-unhandled-return-by-employing-a-void-function.patch usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch usb-dwc3-gadget-update-chain-bit-correctly-when-using-sg-list.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-5.4/arm-dts-dra76x-fix-mmc3-max-frequency.patch b/queue-5.4/arm-dts-dra76x-fix-mmc3-max-frequency.patch new file mode 100644 index 00000000000..79e50ce5145 --- /dev/null +++ b/queue-5.4/arm-dts-dra76x-fix-mmc3-max-frequency.patch @@ -0,0 +1,34 @@ +From fa63c0039787b8fbacf4d6a51e3ff44288f5b90b Mon Sep 17 00:00:00 2001 +From: Faiz Abbas +Date: Tue, 28 Jan 2020 19:17:59 +0530 +Subject: arm: dts: dra76x: Fix mmc3 max-frequency + +From: Faiz Abbas + +commit fa63c0039787b8fbacf4d6a51e3ff44288f5b90b upstream. + +dra76x is not affected by i887 which requires mmc3 node to be limited to +a max frequency of 64 MHz. Fix this by overwriting the correct value in +the the dra76 specific dtsi. + +Fixes: 895bd4b3e5ec ("ARM: dts: Add support for dra76-evm") +Cc: stable@vger.kernel.org +Signed-off-by: Faiz Abbas +Signed-off-by: Tony Lindgren +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/dra76x.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/arm/boot/dts/dra76x.dtsi ++++ b/arch/arm/boot/dts/dra76x.dtsi +@@ -86,3 +86,8 @@ + &usb4_tm { + status = "disabled"; + }; ++ ++&mmc3 { ++ /* dra76x is not affected by i887 */ ++ max-frequency = <96000000>; ++}; diff --git a/queue-5.4/arm64-dts-socfpga-agilex-fix-gmac-compatible.patch b/queue-5.4/arm64-dts-socfpga-agilex-fix-gmac-compatible.patch new file mode 100644 index 00000000000..add70a1d69c --- /dev/null +++ b/queue-5.4/arm64-dts-socfpga-agilex-fix-gmac-compatible.patch @@ -0,0 +1,51 @@ +From 8c867387160e89c9ffd12459f38e56844312a7a7 Mon Sep 17 00:00:00 2001 +From: Ley Foon Tan +Date: Thu, 27 Feb 2020 04:20:14 +0800 +Subject: arm64: dts: socfpga: agilex: Fix gmac compatible + +From: Ley Foon Tan + +commit 8c867387160e89c9ffd12459f38e56844312a7a7 upstream. + +Fix gmac compatible string to "altr,socfpga-stmmac-a10-s10". Gmac for +Agilex should use same compatible as Stratix 10. + +Fixes: 4b36daf9ada3 ("arm64: dts: agilex: Add initial support for Intel's Agilex SoCFPGA") +Cc: stable@vger.kernel.org +Signed-off-by: Ley Foon Tan +Signed-off-by: Dinh Nguyen +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/boot/dts/intel/socfpga_agilex.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi ++++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +@@ -82,7 +82,7 @@ + ranges = <0 0 0 0xffffffff>; + + gmac0: ethernet@ff800000 { +- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; ++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; + reg = <0xff800000 0x2000>; + interrupts = <0 90 4>; + interrupt-names = "macirq"; +@@ -97,7 +97,7 @@ + }; + + gmac1: ethernet@ff802000 { +- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; ++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; + reg = <0xff802000 0x2000>; + interrupts = <0 91 4>; + interrupt-names = "macirq"; +@@ -112,7 +112,7 @@ + }; + + gmac2: ethernet@ff804000 { +- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; ++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; + reg = <0xff804000 0x2000>; + interrupts = <0 92 4>; + interrupt-names = "macirq"; diff --git a/queue-5.4/btrfs-fix-raid-direct-i-o-reads-with-alternate-csums.patch b/queue-5.4/btrfs-fix-raid-direct-i-o-reads-with-alternate-csums.patch new file mode 100644 index 00000000000..80ac727f32e --- /dev/null +++ b/queue-5.4/btrfs-fix-raid-direct-i-o-reads-with-alternate-csums.patch @@ -0,0 +1,58 @@ +From e7a04894c766daa4248cb736efee93550f2d5872 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Mon, 2 Mar 2020 14:02:49 -0800 +Subject: btrfs: fix RAID direct I/O reads with alternate csums + +From: Omar Sandoval + +commit e7a04894c766daa4248cb736efee93550f2d5872 upstream. + +btrfs_lookup_and_bind_dio_csum() does pointer arithmetic which assumes +32-bit checksums. If using a larger checksum, this leads to spurious +failures when a direct I/O read crosses a stripe. This is easy +to reproduce: + + # mkfs.btrfs -f --checksum blake2 -d raid0 /dev/vdc /dev/vdd + ... + # mount /dev/vdc /mnt + # cd /mnt + # dd if=/dev/urandom of=foo bs=1M count=1 status=none + # dd if=foo of=/dev/null bs=1M iflag=direct status=none + dd: error reading 'foo': Input/output error + # dmesg | tail -1 + [ 135.821568] BTRFS warning (device vdc): csum failed root 5 ino 257 off 421888 ... + +Fix it by using the actual checksum size. + +Fixes: 1e25a2e3ca0d ("btrfs: don't assume ordered sums to be 4 bytes") +CC: stable@vger.kernel.org # 5.4+ +Reviewed-by: Johannes Thumshirn +Signed-off-by: Omar Sandoval +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -8426,6 +8426,7 @@ static inline blk_status_t btrfs_lookup_ + { + struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); + struct btrfs_io_bio *orig_io_bio = btrfs_io_bio(dip->orig_bio); ++ u16 csum_size; + blk_status_t ret; + + /* +@@ -8445,7 +8446,8 @@ static inline blk_status_t btrfs_lookup_ + + file_offset -= dip->logical_offset; + file_offset >>= inode->i_sb->s_blocksize_bits; +- io_bio->csum = (u8 *)(((u32 *)orig_io_bio->csum) + file_offset); ++ csum_size = btrfs_super_csum_size(btrfs_sb(inode->i_sb)->super_copy); ++ io_bio->csum = orig_io_bio->csum + csum_size * file_offset; + + return 0; + } diff --git a/queue-5.4/fat-fix-uninit-memory-access-for-partial-initialized-inode.patch b/queue-5.4/fat-fix-uninit-memory-access-for-partial-initialized-inode.patch new file mode 100644 index 00000000000..280debf7cb3 --- /dev/null +++ b/queue-5.4/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 +@@ -749,6 +749,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; + } + +@@ -1373,16 +1380,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); +@@ -1843,13 +1840,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-5.4/locks-fix-a-potential-use-after-free-problem-when-wakeup-a-waiter.patch b/queue-5.4/locks-fix-a-potential-use-after-free-problem-when-wakeup-a-waiter.patch new file mode 100644 index 00000000000..dc5fd5dac4e --- /dev/null +++ b/queue-5.4/locks-fix-a-potential-use-after-free-problem-when-wakeup-a-waiter.patch @@ -0,0 +1,77 @@ +From 6d390e4b5d48ec03bb87e63cf0a2bff5f4e116da Mon Sep 17 00:00:00 2001 +From: yangerkun +Date: Wed, 4 Mar 2020 15:25:56 +0800 +Subject: locks: fix a potential use-after-free problem when wakeup a waiter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: yangerkun + +commit 6d390e4b5d48ec03bb87e63cf0a2bff5f4e116da upstream. + +'16306a61d3b7 ("fs/locks: always delete_block after waiting.")' add the +logic to check waiter->fl_blocker without blocked_lock_lock. And it will +trigger a UAF when we try to wakeup some waiter: + +Thread 1 has create a write flock a on file, and now thread 2 try to +unlock and delete flock a, thread 3 try to add flock b on the same file. + +Thread2 Thread3 + flock syscall(create flock b) + ...flock_lock_inode_wait + flock_lock_inode(will insert + our fl_blocked_member list + to flock a's fl_blocked_requests) + sleep +flock syscall(unlock) +...flock_lock_inode_wait + locks_delete_lock_ctx + ...__locks_wake_up_blocks + __locks_delete_blocks( + b->fl_blocker = NULL) + ... + break by a signal + locks_delete_block + b->fl_blocker == NULL && + list_empty(&b->fl_blocked_requests) + success, return directly + locks_free_lock b + wake_up(&b->fl_waiter) + trigger UAF + +Fix it by remove this logic, and this patch may also fix CVE-2019-19769. + +Cc: stable@vger.kernel.org +Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.") +Signed-off-by: yangerkun +Signed-off-by: Jeff Layton +Signed-off-by: Greg Kroah-Hartman + +--- + fs/locks.c | 14 -------------- + 1 file changed, 14 deletions(-) + +--- a/fs/locks.c ++++ b/fs/locks.c +@@ -753,20 +753,6 @@ int locks_delete_block(struct file_lock + { + int status = -ENOENT; + +- /* +- * If fl_blocker is NULL, it won't be set again as this thread +- * "owns" the lock and is the only one that might try to claim +- * the lock. So it is safe to test fl_blocker locklessly. +- * Also if fl_blocker is NULL, this waiter is not listed on +- * fl_blocked_requests for some lock, so no other request can +- * be added to the list of fl_blocked_requests for this +- * request. So if fl_blocker is NULL, it is safe to +- * locklessly check if fl_blocked_requests is empty. If both +- * of these checks succeed, there is no need to take the lock. +- */ +- if (waiter->fl_blocker == NULL && +- list_empty(&waiter->fl_blocked_requests)) +- return status; + spin_lock(&blocked_lock_lock); + if (waiter->fl_blocker) + status = 0; diff --git a/queue-5.4/mm-fix-possible-pmd-dirty-bit-lost-in-set_pmd_migration_entry.patch b/queue-5.4/mm-fix-possible-pmd-dirty-bit-lost-in-set_pmd_migration_entry.patch new file mode 100644 index 00000000000..97861f3321b --- /dev/null +++ b/queue-5.4/mm-fix-possible-pmd-dirty-bit-lost-in-set_pmd_migration_entry.patch @@ -0,0 +1,56 @@ +From 8a8683ad9ba48b4b52a57f013513d1635c1ca5c4 Mon Sep 17 00:00:00 2001 +From: Huang Ying +Date: Thu, 5 Mar 2020 22:28:29 -0800 +Subject: mm: fix possible PMD dirty bit lost in set_pmd_migration_entry() + +From: Huang Ying + +commit 8a8683ad9ba48b4b52a57f013513d1635c1ca5c4 upstream. + +In set_pmd_migration_entry(), pmdp_invalidate() is used to change PMD +atomically. But the PMD is read before that with an ordinary memory +reading. If the THP (transparent huge page) is written between the PMD +reading and pmdp_invalidate(), the PMD dirty bit may be lost, and cause +data corruption. The race window is quite small, but still possible in +theory, so need to be fixed. + +The race is fixed via using the return value of pmdp_invalidate() to get +the original content of PMD, which is a read/modify/write atomic +operation. So no THP writing can occur in between. + +The race has been introduced when the THP migration support is added in +the commit 616b8371539a ("mm: thp: enable thp migration in generic path"). +But this fix depends on the commit d52605d7cb30 ("mm: do not lose dirty +and accessed bits in pmdp_invalidate()"). So it's easy to be backported +after v4.16. But the race window is really small, so it may be fine not +to backport the fix at all. + +Signed-off-by: Andrew Morton +Signed-off-by: "Huang, Ying" +Reviewed-by: Zi Yan +Reviewed-by: William Kucharski +Acked-by: Kirill A. Shutemov +Cc: +Cc: Vlastimil Babka +Cc: Michal Hocko +Cc: Andrea Arcangeli +Link: http://lkml.kernel.org/r/20200220075220.2327056-1-ying.huang@intel.com +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/huge_memory.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -3032,8 +3032,7 @@ void set_pmd_migration_entry(struct page + return; + + flush_cache_range(vma, address, address + HPAGE_PMD_SIZE); +- pmdval = *pvmw->pmd; +- pmdp_invalidate(vma, address, pvmw->pmd); ++ pmdval = pmdp_invalidate(vma, address, pvmw->pmd); + if (pmd_dirty(pmdval)) + set_page_dirty(page); + entry = make_migration_entry(page, pmd_write(pmdval)); diff --git a/queue-5.4/mm-hotplug-fix-page-online-with-debug_pagealloc-compiled-but-not-enabled.patch b/queue-5.4/mm-hotplug-fix-page-online-with-debug_pagealloc-compiled-but-not-enabled.patch new file mode 100644 index 00000000000..8caf5b678c7 --- /dev/null +++ b/queue-5.4/mm-hotplug-fix-page-online-with-debug_pagealloc-compiled-but-not-enabled.patch @@ -0,0 +1,109 @@ +From c87cbc1f007c4b46165f05ceca04e1973cda0b9c Mon Sep 17 00:00:00 2001 +From: Vlastimil Babka +Date: Thu, 5 Mar 2020 22:28:42 -0800 +Subject: mm, hotplug: fix page online with DEBUG_PAGEALLOC compiled but not enabled + +From: Vlastimil Babka + +commit c87cbc1f007c4b46165f05ceca04e1973cda0b9c upstream. + +Commit cd02cf1aceea ("mm/hotplug: fix an imbalance with DEBUG_PAGEALLOC") +fixed memory hotplug with debug_pagealloc enabled, where onlining a page +goes through page freeing, which removes the direct mapping. Some arches +don't like when the page is not mapped in the first place, so +generic_online_page() maps it first. This is somewhat wasteful, but +better than special casing page freeing fast paths. + +The commit however missed that DEBUG_PAGEALLOC configured doesn't mean +it's actually enabled. One has to test debug_pagealloc_enabled() since +031bc5743f15 ("mm/debug-pagealloc: make debug-pagealloc boottime +configurable"), or alternatively debug_pagealloc_enabled_static() since +8e57f8acbbd1 ("mm, debug_pagealloc: don't rely on static keys too early"), +but this is not done. + +As a result, a s390 kernel with DEBUG_PAGEALLOC configured but not enabled +will crash: + +Unable to handle kernel pointer dereference in virtual kernel address space +Failing address: 0000000000000000 TEID: 0000000000000483 +Fault in home space mode while using kernel ASCE. +AS:0000001ece13400b R2:000003fff7fd000b R3:000003fff7fcc007 S:000003fff7fd7000 P:000000000000013d +Oops: 0004 ilc:2 [#1] SMP +CPU: 1 PID: 26015 Comm: chmem Kdump: loaded Tainted: GX 5.3.18-5-default #1 SLE15-SP2 (unreleased) +Krnl PSW : 0704e00180000000 0000001ecd281b9e (__kernel_map_pages+0x166/0x188) +R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3 +Krnl GPRS: 0000000000000000 0000000000000800 0000400b00000000 0000000000000100 +0000000000000001 0000000000000000 0000000000000002 0000000000000100 +0000001ece139230 0000001ecdd98d40 0000400b00000100 0000000000000000 +000003ffa17e4000 001fffe0114f7d08 0000001ecd4d93ea 001fffe0114f7b20 +Krnl Code: 0000001ecd281b8e: ec17ffff00d8 ahik %r1,%r7,-1 +0000001ecd281b94: ec111dbc0355 risbg %r1,%r1,29,188,3 +>0000001ecd281b9e: 94fb5006 ni 6(%r5),251 +0000001ecd281ba2: 41505008 la %r5,8(%r5) +0000001ecd281ba6: ec51fffc6064 cgrj %r5,%r1,6,1ecd281b9e +0000001ecd281bac: 1a07 ar %r0,%r7 +0000001ecd281bae: ec03ff584076 crj %r0,%r3,4,1ecd281a5e +Call Trace: +[<0000001ecd281b9e>] __kernel_map_pages+0x166/0x188 +[<0000001ecd4d9516>] online_pages_range+0xf6/0x128 +[<0000001ecd2a8186>] walk_system_ram_range+0x7e/0xd8 +[<0000001ecda28aae>] online_pages+0x2fe/0x3f0 +[<0000001ecd7d02a6>] memory_subsys_online+0x8e/0xc0 +[<0000001ecd7add42>] device_online+0x5a/0xc8 +[<0000001ecd7d0430>] state_store+0x88/0x118 +[<0000001ecd5b9f62>] kernfs_fop_write+0xc2/0x200 +[<0000001ecd5064b6>] vfs_write+0x176/0x1e0 +[<0000001ecd50676a>] ksys_write+0xa2/0x100 +[<0000001ecda315d4>] system_call+0xd8/0x2c8 + +Fix this by checking debug_pagealloc_enabled_static() before calling +kernel_map_pages(). Backports for kernel before 5.5 should use +debug_pagealloc_enabled() instead. Also add comments. + +Fixes: cd02cf1aceea ("mm/hotplug: fix an imbalance with DEBUG_PAGEALLOC") +Reported-by: Gerald Schaefer +Signed-off-by: Andrew Morton +Signed-off-by: Vlastimil Babka +Reviewed-by: David Hildenbrand +Cc: +Cc: Joonsoo Kim +Cc: Qian Cai +Link: http://lkml.kernel.org/r/20200224094651.18257-1-vbabka@suse.cz +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/mm.h | 4 ++++ + mm/memory_hotplug.c | 8 +++++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -2695,6 +2695,10 @@ static inline bool debug_pagealloc_enabl + #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP) + extern void __kernel_map_pages(struct page *page, int numpages, int enable); + ++/* ++ * When called in DEBUG_PAGEALLOC context, the call should most likely be ++ * guarded by debug_pagealloc_enabled() or debug_pagealloc_enabled_static() ++ */ + static inline void + kernel_map_pages(struct page *page, int numpages, int enable) + { +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -598,7 +598,13 @@ EXPORT_SYMBOL_GPL(__online_page_free); + + static void generic_online_page(struct page *page, unsigned int order) + { +- kernel_map_pages(page, 1 << order, 1); ++ /* ++ * Freeing the page with debug_pagealloc enabled will try to unmap it, ++ * so we should map it first. This is better than introducing a special ++ * case in page freeing fast path. ++ */ ++ if (debug_pagealloc_enabled_static()) ++ kernel_map_pages(page, 1 << order, 1); + __free_pages_core(page, order); + totalram_pages_add(1UL << order); + #ifdef CONFIG_HIGHMEM diff --git a/queue-5.4/mm-numa-fix-bad-pmd-by-atomically-check-for-pmd_trans_huge-when-marking-page-tables-prot_numa.patch b/queue-5.4/mm-numa-fix-bad-pmd-by-atomically-check-for-pmd_trans_huge-when-marking-page-tables-prot_numa.patch new file mode 100644 index 00000000000..c3e363886bb --- /dev/null +++ b/queue-5.4/mm-numa-fix-bad-pmd-by-atomically-check-for-pmd_trans_huge-when-marking-page-tables-prot_numa.patch @@ -0,0 +1,134 @@ +From 8b272b3cbbb50a6a8e62d8a15affd473a788e184 Mon Sep 17 00:00:00 2001 +From: Mel Gorman +Date: Thu, 5 Mar 2020 22:28:26 -0800 +Subject: mm, numa: fix bad pmd by atomically check for pmd_trans_huge when marking page tables prot_numa + +From: Mel Gorman + +commit 8b272b3cbbb50a6a8e62d8a15affd473a788e184 upstream. + +: A user reported a bug against a distribution kernel while running a +: proprietary workload described as "memory intensive that is not swapping" +: that is expected to apply to mainline kernels. The workload is +: read/write/modifying ranges of memory and checking the contents. They +: reported that within a few hours that a bad PMD would be reported followed +: by a memory corruption where expected data was all zeros. A partial +: report of the bad PMD looked like +: +: [ 5195.338482] ../mm/pgtable-generic.c:33: bad pmd ffff8888157ba008(000002e0396009e2) +: [ 5195.341184] ------------[ cut here ]------------ +: [ 5195.356880] kernel BUG at ../mm/pgtable-generic.c:35! +: .... +: [ 5195.410033] Call Trace: +: [ 5195.410471] [] change_protection_range+0x7dd/0x930 +: [ 5195.410716] [] change_prot_numa+0x18/0x30 +: [ 5195.410918] [] task_numa_work+0x1fe/0x310 +: [ 5195.411200] [] task_work_run+0x72/0x90 +: [ 5195.411246] [] exit_to_usermode_loop+0x91/0xc2 +: [ 5195.411494] [] prepare_exit_to_usermode+0x31/0x40 +: [ 5195.411739] [] retint_user+0x8/0x10 +: +: Decoding revealed that the PMD was a valid prot_numa PMD and the bad PMD +: was a false detection. The bug does not trigger if automatic NUMA +: balancing or transparent huge pages is disabled. +: +: The bug is due a race in change_pmd_range between a pmd_trans_huge and +: pmd_nond_or_clear_bad check without any locks held. During the +: pmd_trans_huge check, a parallel protection update under lock can have +: cleared the PMD and filled it with a prot_numa entry between the transhuge +: check and the pmd_none_or_clear_bad check. +: +: While this could be fixed with heavy locking, it's only necessary to make +: a copy of the PMD on the stack during change_pmd_range and avoid races. A +: new helper is created for this as the check if quite subtle and the +: existing similar helpful is not suitable. This passed 154 hours of +: testing (usually triggers between 20 minutes and 24 hours) without +: detecting bad PMDs or corruption. A basic test of an autonuma-intensive +: workload showed no significant change in behaviour. + +Although Mel withdrew the patch on the face of LKML comment +https://lkml.org/lkml/2017/4/10/922 the race window aforementioned is +still open, and we have reports of Linpack test reporting bad residuals +after the bad PMD warning is observed. In addition to that, bad +rss-counter and non-zero pgtables assertions are triggered on mm teardown +for the task hitting the bad PMD. + + host kernel: mm/pgtable-generic.c:40: bad pmd 00000000b3152f68(8000000d2d2008e7) + .... + host kernel: BUG: Bad rss-counter state mm:00000000b583043d idx:1 val:512 + host kernel: BUG: non-zero pgtables_bytes on freeing mm: 4096 + +The issue is observed on a v4.18-based distribution kernel, but the race +window is expected to be applicable to mainline kernels, as well. + +[akpm@linux-foundation.org: fix comment typo, per Rafael] +Signed-off-by: Andrew Morton +Signed-off-by: Rafael Aquini +Signed-off-by: Mel Gorman +Cc: +Cc: Zi Yan +Cc: "Kirill A. Shutemov" +Cc: Vlastimil Babka +Cc: Michal Hocko +Link: http://lkml.kernel.org/r/20200216191800.22423-1-aquini@redhat.com +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/mprotect.c | 38 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +--- a/mm/mprotect.c ++++ b/mm/mprotect.c +@@ -161,6 +161,31 @@ static unsigned long change_pte_range(st + return pages; + } + ++/* ++ * Used when setting automatic NUMA hinting protection where it is ++ * critical that a numa hinting PMD is not confused with a bad PMD. ++ */ ++static inline int pmd_none_or_clear_bad_unless_trans_huge(pmd_t *pmd) ++{ ++ pmd_t pmdval = pmd_read_atomic(pmd); ++ ++ /* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */ ++#ifdef CONFIG_TRANSPARENT_HUGEPAGE ++ barrier(); ++#endif ++ ++ if (pmd_none(pmdval)) ++ return 1; ++ if (pmd_trans_huge(pmdval)) ++ return 0; ++ if (unlikely(pmd_bad(pmdval))) { ++ pmd_clear_bad(pmd); ++ return 1; ++ } ++ ++ return 0; ++} ++ + static inline unsigned long change_pmd_range(struct vm_area_struct *vma, + pud_t *pud, unsigned long addr, unsigned long end, + pgprot_t newprot, int dirty_accountable, int prot_numa) +@@ -178,8 +203,17 @@ static inline unsigned long change_pmd_r + unsigned long this_pages; + + next = pmd_addr_end(addr, end); +- if (!is_swap_pmd(*pmd) && !pmd_trans_huge(*pmd) && !pmd_devmap(*pmd) +- && pmd_none_or_clear_bad(pmd)) ++ ++ /* ++ * Automatic NUMA balancing walks the tables with mmap_sem ++ * held for read. It's possible a parallel update to occur ++ * between pmd_trans_huge() and a pmd_none_or_clear_bad() ++ * check leading to a false positive and clearing. ++ * Hence, it's necessary to atomically read the PMD value ++ * for all the checks. ++ */ ++ if (!is_swap_pmd(*pmd) && !pmd_devmap(*pmd) && ++ pmd_none_or_clear_bad_unless_trans_huge(pmd)) + goto next; + + /* invoke the mmu notifier if the pmd is populated */ diff --git a/queue-5.4/revert-software-node-simplify-software_node_release-function.patch b/queue-5.4/revert-software-node-simplify-software_node_release-function.patch new file mode 100644 index 00000000000..b9bd91ad87c --- /dev/null +++ b/queue-5.4/revert-software-node-simplify-software_node_release-function.patch @@ -0,0 +1,92 @@ +From 7589238a8cf37331607c3222a64ac3140b29532d Mon Sep 17 00:00:00 2001 +From: Brendan Higgins +Date: Thu, 27 Feb 2020 16:00:01 -0800 +Subject: Revert "software node: Simplify software_node_release() function" + +From: Brendan Higgins + +commit 7589238a8cf37331607c3222a64ac3140b29532d upstream. + +This reverts commit 3df85a1ae51f6b256982fe9d17c2dc5bfb4cc402. + +The reverted commit says "It's possible to release the node ID +immediately when fwnode_remove_software_node() is called, no need to +wait for software_node_release() with that." However, releasing the node +ID before waiting for software_node_release() to be called causes the +node ID to be released before the kobject and the underlying sysfs +entry; this means there is a period of time where a sysfs entry exists +that is associated with an unallocated node ID. + +Once consequence of this is that there is a race condition where it is +possible to call fwnode_create_software_node() with no parent node +specified (NULL) and have it fail with -EEXIST because the node ID that +was assigned is still associated with a stale sysfs entry that hasn't +been cleaned up yet. + +Although it is difficult to reproduce this race condition under normal +conditions, it can be deterministically reproduced with the following +minconfig on UML: + +CONFIG_KUNIT_DRIVER_PE_TEST=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_KOBJECT_RELEASE=y +CONFIG_KUNIT=y + +Running the tests with this configuration causes the following failure: + + +kobject: 'node0' ((____ptrval____)): kobject_release, parent (____ptrval____) (delayed 400) + ok 1 - pe_test_uints +sysfs: cannot create duplicate filename '/kernel/software_nodes/node0' +CPU: 0 PID: 28 Comm: kunit_try_catch Not tainted 5.6.0-rc3-next-20200227 #14 + +kobject_add_internal failed for node0 with -EEXIST, don't try to register things with the same name in the same directory. +kobject: 'node0' ((____ptrval____)): kobject_release, parent (____ptrval____) (delayed 100) + # pe_test_uint_arrays: ASSERTION FAILED at drivers/base/test/property-entry-test.c:123 + Expected node is not error, but is: -17 + not ok 2 - pe_test_uint_arrays + + +Reported-by: Heidi Fahim +Signed-off-by: Brendan Higgins +Reviewed-by: Heikki Krogerus +Cc: 5.3+ # 5.3+ +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/swnode.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/base/swnode.c ++++ b/drivers/base/swnode.c +@@ -679,6 +679,13 @@ static void software_node_release(struct + { + struct swnode *swnode = kobj_to_swnode(kobj); + ++ if (swnode->parent) { ++ ida_simple_remove(&swnode->parent->child_ids, swnode->id); ++ list_del(&swnode->entry); ++ } else { ++ ida_simple_remove(&swnode_root_ids, swnode->id); ++ } ++ + if (swnode->allocated) { + property_entries_free(swnode->node->properties); + kfree(swnode->node); +@@ -844,13 +851,6 @@ void fwnode_remove_software_node(struct + if (!swnode) + return; + +- if (swnode->parent) { +- ida_simple_remove(&swnode->parent->child_ids, swnode->id); +- list_del(&swnode->entry); +- } else { +- ida_simple_remove(&swnode_root_ids, swnode->id); +- } +- + kobject_put(&swnode->kobj); + } + EXPORT_SYMBOL_GPL(fwnode_remove_software_node); diff --git a/queue-5.4/serial-8250_exar-add-support-for-acces-cards.patch b/queue-5.4/serial-8250_exar-add-support-for-acces-cards.patch new file mode 100644 index 00000000000..ae9779c2f61 --- /dev/null +++ b/queue-5.4/serial-8250_exar-add-support-for-acces-cards.patch @@ -0,0 +1,76 @@ +From 10c5ccc3c6d32f3d7d6c07de1d3f0f4b52f3e3ab Mon Sep 17 00:00:00 2001 +From: Jay Dolan +Date: Thu, 5 Mar 2020 06:05:04 -0800 +Subject: serial: 8250_exar: add support for ACCES cards + +From: Jay Dolan + +commit 10c5ccc3c6d32f3d7d6c07de1d3f0f4b52f3e3ab upstream. + +Add ACCES VIDs and PIDs that use the Exar chips + +Signed-off-by: Jay Dolan +Cc: stable +Link: https://lore.kernel.org/r/20200305140504.22237-1-jay.dolan@accesio.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250/8250_exar.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- a/drivers/tty/serial/8250/8250_exar.c ++++ b/drivers/tty/serial/8250/8250_exar.c +@@ -25,6 +25,14 @@ + + #include "8250.h" + ++#define PCI_DEVICE_ID_ACCES_COM_2S 0x1052 ++#define PCI_DEVICE_ID_ACCES_COM_4S 0x105d ++#define PCI_DEVICE_ID_ACCES_COM_8S 0x106c ++#define PCI_DEVICE_ID_ACCES_COM232_8 0x10a8 ++#define PCI_DEVICE_ID_ACCES_COM_2SM 0x10d2 ++#define PCI_DEVICE_ID_ACCES_COM_4SM 0x10db ++#define PCI_DEVICE_ID_ACCES_COM_8SM 0x10ea ++ + #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 + #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 + #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a +@@ -658,6 +666,22 @@ static int __maybe_unused exar_resume(st + + static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume); + ++static const struct exar8250_board acces_com_2x = { ++ .num_ports = 2, ++ .setup = pci_xr17c154_setup, ++}; ++ ++static const struct exar8250_board acces_com_4x = { ++ .num_ports = 4, ++ .setup = pci_xr17c154_setup, ++}; ++ ++static const struct exar8250_board acces_com_8x = { ++ .num_ports = 8, ++ .setup = pci_xr17c154_setup, ++}; ++ ++ + static const struct exar8250_board pbn_fastcom335_2 = { + .num_ports = 2, + .setup = pci_fastcom335_setup, +@@ -726,6 +750,15 @@ static const struct exar8250_board pbn_e + } + + static const struct pci_device_id exar_pci_tbl[] = { ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_2S, acces_com_2x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_4S, acces_com_4x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_8S, acces_com_8x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM232_8, acces_com_8x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_2SM, acces_com_2x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_4SM, acces_com_4x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_8SM, acces_com_8x), ++ ++ + CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect), diff --git a/queue-5.4/series b/queue-5.4/series index c6faee75f4f..74ee4890ce5 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -63,3 +63,26 @@ alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-master.patch alsa-hda-realtek-enable-the-headset-of-asus-b9450fa-with-alc294.patch cifs-don-t-leak-eagain-for-stat-during-reconnect.patch cifs-fix-rename-by-ensuring-source-handle-opened-with-delete-bit.patch +usb-storage-add-quirk-for-samsung-fit-flash.patch +usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch +usb-dwc3-gadget-update-chain-bit-correctly-when-using-sg-list.patch +usb-cdns3-gadget-link-trb-should-point-to-next-request.patch +usb-cdns3-gadget-toggle-cycle-bit-before-reset-endpoint.patch +usb-core-hub-fix-unhandled-return-by-employing-a-void-function.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 +locks-fix-a-potential-use-after-free-problem-when-wakeup-a-waiter.patch +mm-numa-fix-bad-pmd-by-atomically-check-for-pmd_trans_huge-when-marking-page-tables-prot_numa.patch +mm-fix-possible-pmd-dirty-bit-lost-in-set_pmd_migration_entry.patch +mm-hotplug-fix-page-online-with-debug_pagealloc-compiled-but-not-enabled.patch +fat-fix-uninit-memory-access-for-partial-initialized-inode.patch +revert-software-node-simplify-software_node_release-function.patch +btrfs-fix-raid-direct-i-o-reads-with-alternate-csums.patch +arm64-dts-socfpga-agilex-fix-gmac-compatible.patch +arm-dts-dra76x-fix-mmc3-max-frequency.patch +tty-serial-mvebu-uart-fix-a-wrong-return.patch +tty-serial-fsl_lpuart-free-ids-allocated-by-ida.patch +serial-8250_exar-add-support-for-acces-cards.patch +vt-selection-close-sel_buffer-race.patch +vt-selection-push-console-lock-down.patch diff --git a/queue-5.4/tty-serial-fsl_lpuart-free-ids-allocated-by-ida.patch b/queue-5.4/tty-serial-fsl_lpuart-free-ids-allocated-by-ida.patch new file mode 100644 index 00000000000..a3ed21896bd --- /dev/null +++ b/queue-5.4/tty-serial-fsl_lpuart-free-ids-allocated-by-ida.patch @@ -0,0 +1,108 @@ +From 2b2e71fe657510a6f71aa16ef0309fa6bc20ab3d Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 3 Mar 2020 18:42:59 +0100 +Subject: tty: serial: fsl_lpuart: free IDs allocated by IDA + +From: Michael Walle + +commit 2b2e71fe657510a6f71aa16ef0309fa6bc20ab3d upstream. + +Since commit 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node +dependence") the port line number can also be allocated by IDA, but in +case of an error the ID will no be removed again. More importantly, any +ID will be freed in remove(), even if it wasn't allocated but instead +fetched by of_alias_get_id(). If it was not allocated by IDA there will +be a warning: + WARN(1, "ida_free called for id=%d which is not allocated.\n", id); + +Move the ID allocation more to the end of the probe() so that we still +can use plain return in the first error cases. + +Fixes: 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node dependence") +Signed-off-by: Michael Walle +Cc: stable +Link: https://lore.kernel.org/r/20200303174306.6015-3-michael@walle.cc +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/fsl_lpuart.c | 39 ++++++++++++++++++++++++--------------- + 1 file changed, 24 insertions(+), 15 deletions(-) + +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -268,6 +268,7 @@ struct lpuart_port { + int rx_dma_rng_buf_len; + unsigned int dma_tx_nents; + wait_queue_head_t dma_wait; ++ bool id_allocated; + }; + + struct lpuart_soc_data { +@@ -2382,19 +2383,6 @@ static int lpuart_probe(struct platform_ + if (!sport) + return -ENOMEM; + +- ret = of_alias_get_id(np, "serial"); +- if (ret < 0) { +- ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); +- if (ret < 0) { +- dev_err(&pdev->dev, "port line is full, add device failed\n"); +- return ret; +- } +- } +- if (ret >= ARRAY_SIZE(lpuart_ports)) { +- dev_err(&pdev->dev, "serial%d out of range\n", ret); +- return -EINVAL; +- } +- sport->port.line = ret; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + sport->port.membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(sport->port.membase)) +@@ -2435,9 +2423,25 @@ static int lpuart_probe(struct platform_ + } + } + ++ ret = of_alias_get_id(np, "serial"); ++ if (ret < 0) { ++ ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "port line is full, add device failed\n"); ++ return ret; ++ } ++ sport->id_allocated = true; ++ } ++ if (ret >= ARRAY_SIZE(lpuart_ports)) { ++ dev_err(&pdev->dev, "serial%d out of range\n", ret); ++ ret = -EINVAL; ++ goto failed_out_of_range; ++ } ++ sport->port.line = ret; ++ + ret = lpuart_enable_clks(sport); + if (ret) +- return ret; ++ goto failed_clock_enable; + sport->port.uartclk = lpuart_get_baud_clk_rate(sport); + + lpuart_ports[sport->port.line] = sport; +@@ -2487,6 +2491,10 @@ static int lpuart_probe(struct platform_ + failed_attach_port: + failed_irq_request: + lpuart_disable_clks(sport); ++failed_clock_enable: ++failed_out_of_range: ++ if (sport->id_allocated) ++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line); + return ret; + } + +@@ -2496,7 +2504,8 @@ static int lpuart_remove(struct platform + + uart_remove_one_port(&lpuart_reg, &sport->port); + +- ida_simple_remove(&fsl_lpuart_ida, sport->port.line); ++ if (sport->id_allocated) ++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line); + + lpuart_disable_clks(sport); + diff --git a/queue-5.4/tty-serial-mvebu-uart-fix-a-wrong-return.patch b/queue-5.4/tty-serial-mvebu-uart-fix-a-wrong-return.patch new file mode 100644 index 00000000000..e7bff6162e0 --- /dev/null +++ b/queue-5.4/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 +@@ -851,7 +851,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); + + mvuart = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart), + GFP_KERNEL); diff --git a/queue-5.4/usb-cdns3-gadget-link-trb-should-point-to-next-request.patch b/queue-5.4/usb-cdns3-gadget-link-trb-should-point-to-next-request.patch new file mode 100644 index 00000000000..8c3f1824d15 --- /dev/null +++ b/queue-5.4/usb-cdns3-gadget-link-trb-should-point-to-next-request.patch @@ -0,0 +1,34 @@ +From 8a7c47fb7285b23ca259c888016513d5566fa9e8 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Wed, 19 Feb 2020 22:14:54 +0800 +Subject: usb: cdns3: gadget: link trb should point to next request + +From: Peter Chen + +commit 8a7c47fb7285b23ca259c888016513d5566fa9e8 upstream. + +It has marked the dequeue trb as link trb, but its next segment +pointer is still itself, it causes the transfer can't go on. Fix +it by set its pointer as the trb address for the next request. + +Fixes: f616c3bda47e ("usb: cdns3: Fix dequeue implementation") +Signed-off-by: Peter Chen +Cc: stable +Link: https://lore.kernel.org/r/20200219141455.23257-2-peter.chen@nxp.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/cdns3/gadget.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/cdns3/gadget.c ++++ b/drivers/usb/cdns3/gadget.c +@@ -2107,7 +2107,7 @@ found: + /* Update ring only if removed request is on pending_req_list list */ + if (req_on_hw_ring) { + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + +- (priv_req->start_trb * TRB_SIZE)); ++ ((priv_req->end_trb + 1) * TRB_SIZE)); + link_trb->control = (link_trb->control & TRB_CYCLE) | + TRB_TYPE(TRB_LINK) | TRB_CHAIN; + diff --git a/queue-5.4/usb-cdns3-gadget-toggle-cycle-bit-before-reset-endpoint.patch b/queue-5.4/usb-cdns3-gadget-toggle-cycle-bit-before-reset-endpoint.patch new file mode 100644 index 00000000000..771e27a8b5f --- /dev/null +++ b/queue-5.4/usb-cdns3-gadget-toggle-cycle-bit-before-reset-endpoint.patch @@ -0,0 +1,69 @@ +From 4bf2dd65135a2d7fe202f7c10d65b51bcf645ac6 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Wed, 19 Feb 2020 22:14:55 +0800 +Subject: usb: cdns3: gadget: toggle cycle bit before reset endpoint + +From: Peter Chen + +commit 4bf2dd65135a2d7fe202f7c10d65b51bcf645ac6 upstream. + +If there are TRBs pending during reset endpoint operation, the +DMA will advance after reset operation, but it isn't expected, +since the data is not yet available (For OUT, the data is not +yet available). After the data is ready, there won't be any +interrupt since the EP_TRADDR already points to next TRB entry +and doorbell is not set. + +To fix it, it toggles cycle bit before reset operation, and restores +it after reset, it could avoid unexpected DMA advance due to +cycle bit is for software during the endpoint reset operation. + +Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") +Signed-off-by: Peter Chen +Cc: stable +Link: https://lore.kernel.org/r/20200219141455.23257-3-peter.chen@nxp.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/cdns3/gadget.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/usb/cdns3/gadget.c ++++ b/drivers/usb/cdns3/gadget.c +@@ -2152,11 +2152,21 @@ int __cdns3_gadget_ep_clear_halt(struct + { + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + struct usb_request *request; ++ struct cdns3_request *priv_req; ++ struct cdns3_trb *trb = NULL; + int ret; + int val; + + trace_cdns3_halt(priv_ep, 0, 0); + ++ request = cdns3_next_request(&priv_ep->pending_req_list); ++ if (request) { ++ priv_req = to_cdns3_request(request); ++ trb = priv_req->trb; ++ if (trb) ++ trb->control = trb->control ^ TRB_CYCLE; ++ } ++ + writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); + + /* wait for EPRST cleared */ +@@ -2167,10 +2177,11 @@ int __cdns3_gadget_ep_clear_halt(struct + + priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING); + +- request = cdns3_next_request(&priv_ep->pending_req_list); +- +- if (request) ++ if (request) { ++ if (trb) ++ trb->control = trb->control ^ TRB_CYCLE; + cdns3_rearm_transfer(priv_ep, 1); ++ } + + cdns3_start_all_request(priv_dev, priv_ep); + return ret; diff --git a/queue-5.4/usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch b/queue-5.4/usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch new file mode 100644 index 00000000000..c2dc5208e6b --- /dev/null +++ b/queue-5.4/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 +@@ -987,13 +987,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-5.4/usb-core-hub-fix-unhandled-return-by-employing-a-void-function.patch b/queue-5.4/usb-core-hub-fix-unhandled-return-by-employing-a-void-function.patch new file mode 100644 index 00000000000..c5a0f6fb88b --- /dev/null +++ b/queue-5.4/usb-core-hub-fix-unhandled-return-by-employing-a-void-function.patch @@ -0,0 +1,26 @@ +From 63d6d7ed475c53dc1cabdfedf63de1fd8dcd72ee Mon Sep 17 00:00:00 2001 +From: Eugeniu Rosca +Date: Wed, 26 Feb 2020 18:50:34 +0100 +Subject: usb: core: hub: fix unhandled return by employing a void function + +From: Eugeniu Rosca + +commit 63d6d7ed475c53dc1cabdfedf63de1fd8dcd72ee upstream. + +Address below Coverity complaint (Feb 25, 2020, 8:06 AM CET): + +--- + drivers/usb/core/hub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1865,7 +1865,7 @@ static int hub_probe(struct usb_interfac + + if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) { + hub->quirk_disable_autosuspend = 1; +- usb_autopm_get_interface(intf); ++ usb_autopm_get_interface_no_resume(intf); + } + + if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) diff --git a/queue-5.4/usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch b/queue-5.4/usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch new file mode 100644 index 00000000000..9c3af6686c9 --- /dev/null +++ b/queue-5.4/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 +@@ -213,7 +213,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) { +@@ -266,7 +269,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-5.4/usb-dwc3-gadget-update-chain-bit-correctly-when-using-sg-list.patch b/queue-5.4/usb-dwc3-gadget-update-chain-bit-correctly-when-using-sg-list.patch new file mode 100644 index 00000000000..d0c17f42f3e --- /dev/null +++ b/queue-5.4/usb-dwc3-gadget-update-chain-bit-correctly-when-using-sg-list.patch @@ -0,0 +1,66 @@ +From dad2aff3e827b112f27fa5e6f2bf87a110067c3f Mon Sep 17 00:00:00 2001 +From: Pratham Pratap +Date: Mon, 2 Mar 2020 21:44:43 +0000 +Subject: usb: dwc3: gadget: Update chain bit correctly when using sg list + +From: Pratham Pratap + +commit dad2aff3e827b112f27fa5e6f2bf87a110067c3f upstream. + +If scatter-gather operation is allowed, a large USB request is split +into multiple TRBs. For preparing TRBs for sg list, driver iterates +over the list and creates TRB for each sg and mark the chain bit to +false for the last sg. The current IOMMU driver is clubbing the list +of sgs which shares a page boundary into one and giving it to USB driver. +With this the number of sgs mapped it not equal to the the number of sgs +passed. Because of this USB driver is not marking the chain bit to false +since it couldn't iterate to the last sg. This patch addresses this issue +by marking the chain bit to false if it is the last mapped sg. + +At a practical level, this patch resolves USB transfer stalls +seen with adb on dwc3 based db845c, pixel3 and other qcom +hardware after functionfs gadget added scatter-gather support +around v4.20. + +Credit also to Anurag Kumar Vulisha +who implemented a very similar fix to this issue. + +Cc: Felipe Balbi +Cc: Yang Fei +Cc: Thinh Nguyen +Cc: Tejas Joglekar +Cc: Andrzej Pietrasiewicz +Cc: Jack Pham +Cc: Todd Kjos +Cc: Greg KH +Cc: Linux USB List +Cc: stable #4.20+ +Signed-off-by: Pratham Pratap +[jstultz: Slight tweak to remove sg_is_last() usage, reworked + commit message, minor comment tweak] +Signed-off-by: John Stultz +Link: https://lore.kernel.org/r/20200302214443.55783-1-john.stultz@linaro.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/gadget.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1068,7 +1068,14 @@ static void dwc3_prepare_one_trb_sg(stru + unsigned int rem = length % maxp; + unsigned chain = true; + +- if (sg_is_last(s)) ++ /* ++ * IOMMU driver is coalescing the list of sgs which shares a ++ * page boundary into one and giving it to USB driver. With ++ * this the number of sgs mapped is not equal to the number of ++ * sgs passed. So mark the chain bit to false if it isthe last ++ * mapped sg. ++ */ ++ if (i == remaining - 1) + chain = false; + + if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) { diff --git a/queue-5.4/usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch b/queue-5.4/usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch new file mode 100644 index 00000000000..59ebbc9210a --- /dev/null +++ b/queue-5.4/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 +@@ -231,6 +231,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-5.4/usb-storage-add-quirk-for-samsung-fit-flash.patch b/queue-5.4/usb-storage-add-quirk-for-samsung-fit-flash.patch new file mode 100644 index 00000000000..b8edfac51e4 --- /dev/null +++ b/queue-5.4/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 +@@ -1258,6 +1258,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-5.4/vgacon-fix-a-uaf-in-vgacon_invert_region.patch b/queue-5.4/vgacon-fix-a-uaf-in-vgacon_invert_region.patch new file mode 100644 index 00000000000..22436cbb0ad --- /dev/null +++ b/queue-5.4/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 +@@ -1316,6 +1316,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-5.4/vt-selection-close-sel_buffer-race.patch b/queue-5.4/vt-selection-close-sel_buffer-race.patch new file mode 100644 index 00000000000..39b299e5b61 --- /dev/null +++ b/queue-5.4/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 +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -45,6 +46,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) */ +@@ -186,7 +188,7 @@ int set_selection_kernel(struct tiocl_se + char *bp, *obp; + int i, ps, pe, multiplier; + u32 c; +- int mode; ++ int mode, ret = 0; + + poke_blanked_console(); + +@@ -212,6 +214,7 @@ int set_selection_kernel(struct tiocl_se + if (ps > pe) /* make sel_start <= sel_end */ + swap(ps, pe); + ++ mutex_lock(&sel_lock); + if (sel_cons != vc_cons[fg_console].d) { + clear_selection(); + sel_cons = vc_cons[fg_console].d; +@@ -257,9 +260,10 @@ int set_selection_kernel(struct tiocl_se + break; + case TIOCL_SELPOINTER: + highlight_pointer(pe); +- return 0; ++ goto unlock; + default: +- return -EINVAL; ++ ret = -EINVAL; ++ goto unlock; + } + + /* remove the pointer */ +@@ -281,7 +285,7 @@ int set_selection_kernel(struct tiocl_se + 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 */ +@@ -309,7 +313,8 @@ int set_selection_kernel(struct tiocl_se + if (!bp) { + printk(KERN_WARNING "selection: kmalloc() failed\n"); + clear_selection(); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto unlock; + } + kfree(sel_buffer); + sel_buffer = bp; +@@ -334,7 +339,9 @@ int set_selection_kernel(struct tiocl_se + } + } + sel_buffer_lth = bp - sel_buffer; +- return 0; ++unlock: ++ mutex_unlock(&sel_lock); ++ return ret; + } + EXPORT_SYMBOL_GPL(set_selection_kernel); + +@@ -364,6 +371,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)) { +@@ -371,7 +379,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); +@@ -380,6 +390,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-5.4/vt-selection-push-console-lock-down.patch b/queue-5.4/vt-selection-push-console-lock-down.patch new file mode 100644 index 00000000000..f2cf92ded46 --- /dev/null +++ b/queue-5.4/vt-selection-push-console-lock-down.patch @@ -0,0 +1,81 @@ +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/staging/speakup/selection.c | 2 -- + drivers/tty/vt/selection.c | 13 ++++++++++++- + drivers/tty/vt/vt.c | 2 -- + 3 files changed, 12 insertions(+), 5 deletions(-) + +--- a/drivers/staging/speakup/selection.c ++++ b/drivers/staging/speakup/selection.c +@@ -51,9 +51,7 @@ static void __speakup_set_selection(stru + goto unref; + } + +- console_lock(); + set_selection_kernel(&sel, tty); +- console_unlock(); + + unref: + tty_kref_put(tty); +--- a/drivers/tty/vt/selection.c ++++ b/drivers/tty/vt/selection.c +@@ -181,7 +181,7 @@ int set_selection_user(const struct tioc + return set_selection_kernel(&v, tty); + } + +-int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) ++static int __set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) + { + struct vc_data *vc = vc_cons[fg_console].d; + int new_sel_start, new_sel_end, spc; +@@ -343,6 +343,17 @@ unlock: + mutex_unlock(&sel_lock); + return ret; + } ++ ++int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) ++{ ++ int ret; ++ ++ console_lock(); ++ ret = __set_selection_kernel(v, tty); ++ console_unlock(); ++ ++ return ret; ++} + EXPORT_SYMBOL_GPL(set_selection_kernel); + + /* Insert the contents of the selection buffer into the +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -3046,10 +3046,8 @@ int tioclinux(struct tty_struct *tty, un + switch (type) + { + case TIOCL_SETSEL: +- console_lock(); + ret = set_selection_user((struct tiocl_selection + __user *)(p+1), tty); +- console_unlock(); + break; + case TIOCL_PASTESEL: + ret = paste_selection(tty);