From: Greg Kroah-Hartman Date: Mon, 18 Dec 2017 12:00:42 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v3.18.89~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1cef3ddec8532489a6d5a7914adfa3d8bb59c9cc;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: arm64-fix-config_debug_wx-address-reporting.patch arm64-initialise-high_memory-global-variable-earlier.patch arm64-mm-fix-pte_mkclean-pte_mkdirty-semantics.patch autofs-fix-careless-error-in-recent-commit.patch ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch dm-fix-various-targets-to-dm_register_target-after-module-__init-resources-created.patch dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch eeprom-at24-change-nvmem-stride-to-1.patch ext4-add-missing-error-check-in-__ext4_new_inode.patch ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch ext4-fix-fdatasync-2-after-fallocate-2-operation.patch ext4-support-fast-symlinks-from-ext3-file-systems.patch ib-core-bound-check-alternate-path-port-number.patch ib-core-don-t-enforce-pkey-security-on-smi-mads.patch iw_cxgb4-only-insert-drain-cqes-if-wq-is-flushed.patch kernel-make-groups_sort-calling-a-responsibility-group_info-allocators.patch mm-oom_reaper-fix-memory-corruption.patch mmc-core-apply-no_cmd23-quirk-to-some-specific-cards.patch nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch ovl-pass-ovl_get_nlink-parameters-in-right-order.patch ovl-update-ctx-pos-on-impure-dir-iteration.patch posix-timer-properly-check-sigevent-sigev_notify.patch revert-exec-avoid-rlimit_stack-races-with-prlimit.patch sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch scsi-core-fix-a-scsi_show_rq-null-pointer-dereference.patch scsi-libsas-fix-length-error-in-sas_smp_handler.patch sunrpc-fix-a-race-in-the-receive-code-path.patch tracing-allocate-mask_str-buffer-dynamically.patch usb-core-prevent-malicious-bnuminterfaces-overflow.patch usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch usb-xhci-fix-tds-for-mtk-xhci1.1.patch usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch x86-boot-compressed-64-detect-and-handle-5-level-paging-at-boot-time.patch x86-boot-compressed-64-print-error-if-5-level-paging-is-not-supported.patch xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch --- diff --git a/queue-4.14/arm64-fix-config_debug_wx-address-reporting.patch b/queue-4.14/arm64-fix-config_debug_wx-address-reporting.patch new file mode 100644 index 00000000000..56360892abd --- /dev/null +++ b/queue-4.14/arm64-fix-config_debug_wx-address-reporting.patch @@ -0,0 +1,41 @@ +From 1d08a044cf12aee37dfd54837558e3295287b343 Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Wed, 13 Dec 2017 11:45:42 +0000 +Subject: arm64: fix CONFIG_DEBUG_WX address reporting + +From: Mark Rutland + +commit 1d08a044cf12aee37dfd54837558e3295287b343 upstream. + +In ptdump_check_wx(), we pass walk_pgd() a start address of 0 (rather +than VA_START) for the init_mm. This means that any reported W&X +addresses are offset by VA_START, which is clearly wrong and can make +them appear like userspace addresses. + +Fix this by telling the ptdump code that we're walking init_mm starting +at VA_START. We don't need to update the addr_markers, since these are +still valid bounds regardless. + +Fixes: 1404d6f13e47 ("arm64: dump: Add checking for writable and exectuable pages") +Signed-off-by: Mark Rutland +Cc: Kees Cook +Cc: Laura Abbott +Reported-by: Timur Tabi +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/mm/dump.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/mm/dump.c ++++ b/arch/arm64/mm/dump.c +@@ -389,7 +389,7 @@ void ptdump_check_wx(void) + .check_wx = true, + }; + +- walk_pgd(&st, &init_mm, 0); ++ walk_pgd(&st, &init_mm, VA_START); + note_page(&st, 0, 0, 0); + if (st.wx_pages || st.uxn_pages) + pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UXN pages found\n", diff --git a/queue-4.14/arm64-initialise-high_memory-global-variable-earlier.patch b/queue-4.14/arm64-initialise-high_memory-global-variable-earlier.patch new file mode 100644 index 00000000000..abfbb1956e3 --- /dev/null +++ b/queue-4.14/arm64-initialise-high_memory-global-variable-earlier.patch @@ -0,0 +1,48 @@ +From f24e5834a2c3f6c5f814a417f858226f0a010ade Mon Sep 17 00:00:00 2001 +From: Steve Capper +Date: Mon, 4 Dec 2017 14:13:05 +0000 +Subject: arm64: Initialise high_memory global variable earlier + +From: Steve Capper + +commit f24e5834a2c3f6c5f814a417f858226f0a010ade upstream. + +The high_memory global variable is used by +cma_declare_contiguous(.) before it is defined. + +We don't notice this as we compute __pa(high_memory - 1), and it looks +like we're processing a VA from the direct linear map. + +This problem becomes apparent when we flip the kernel virtual address +space and the linear map is moved to the bottom of the kernel VA space. + +This patch moves the initialisation of high_memory before it used. + +Fixes: f7426b983a6a ("mm: cma: adjust address limit to avoid hitting low/high memory boundary") +Signed-off-by: Steve Capper +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/mm/init.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/arm64/mm/init.c ++++ b/arch/arm64/mm/init.c +@@ -476,6 +476,8 @@ void __init arm64_memblock_init(void) + + reserve_elfcorehdr(); + ++ high_memory = __va(memblock_end_of_DRAM() - 1) + 1; ++ + dma_contiguous_reserve(arm64_dma_phys_limit); + + memblock_allow_resize(); +@@ -502,7 +504,6 @@ void __init bootmem_init(void) + sparse_init(); + zone_sizes_init(min, max); + +- high_memory = __va((max << PAGE_SHIFT) - 1) + 1; + memblock_dump_all(); + } + diff --git a/queue-4.14/arm64-mm-fix-pte_mkclean-pte_mkdirty-semantics.patch b/queue-4.14/arm64-mm-fix-pte_mkclean-pte_mkdirty-semantics.patch new file mode 100644 index 00000000000..6c7f2c83c27 --- /dev/null +++ b/queue-4.14/arm64-mm-fix-pte_mkclean-pte_mkdirty-semantics.patch @@ -0,0 +1,108 @@ +From 8781bcbc5e69d7da69e84c7044ca0284848d5d01 Mon Sep 17 00:00:00 2001 +From: Steve Capper +Date: Fri, 1 Dec 2017 17:22:14 +0000 +Subject: arm64: mm: Fix pte_mkclean, pte_mkdirty semantics + +From: Steve Capper + +commit 8781bcbc5e69d7da69e84c7044ca0284848d5d01 upstream. + +On systems with hardware dirty bit management, the ltp madvise09 unit +test fails due to dirty bit information being lost and pages being +incorrectly freed. + +This was bisected to: + arm64: Ignore hardware dirty bit updates in ptep_set_wrprotect() + +Reverting this commit leads to a separate problem, that the unit test +retains pages that should have been dropped due to the function +madvise_free_pte_range(.) not cleaning pte's properly. + +Currently pte_mkclean only clears the software dirty bit, thus the +following code sequence can appear: + + pte = pte_mkclean(pte); + if (pte_dirty(pte)) + // this condition can return true with HW DBM! + +This patch also adjusts pte_mkclean to set PTE_RDONLY thus effectively +clearing both the SW and HW dirty information. + +In order for this to function on systems without HW DBM, we need to +also adjust pte_mkdirty to remove the read only bit from writable pte's +to avoid infinite fault loops. + +Fixes: 64c26841b349 ("arm64: Ignore hardware dirty bit updates in ptep_set_wrprotect()") +Reported-by: Bhupinder Thakur +Tested-by: Bhupinder Thakur +Reviewed-by: Catalin Marinas +Signed-off-by: Steve Capper +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/pgtable.h | 33 ++++++++++++++++++--------------- + 1 file changed, 18 insertions(+), 15 deletions(-) + +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -149,12 +149,20 @@ static inline pte_t pte_mkwrite(pte_t pt + + static inline pte_t pte_mkclean(pte_t pte) + { +- return clear_pte_bit(pte, __pgprot(PTE_DIRTY)); ++ pte = clear_pte_bit(pte, __pgprot(PTE_DIRTY)); ++ pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); ++ ++ return pte; + } + + static inline pte_t pte_mkdirty(pte_t pte) + { +- return set_pte_bit(pte, __pgprot(PTE_DIRTY)); ++ pte = set_pte_bit(pte, __pgprot(PTE_DIRTY)); ++ ++ if (pte_write(pte)) ++ pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); ++ ++ return pte; + } + + static inline pte_t pte_mkold(pte_t pte) +@@ -642,28 +650,23 @@ static inline pmd_t pmdp_huge_get_and_cl + #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + + /* +- * ptep_set_wrprotect - mark read-only while preserving the hardware update of +- * the Access Flag. ++ * ptep_set_wrprotect - mark read-only while trasferring potential hardware ++ * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit. + */ + #define __HAVE_ARCH_PTEP_SET_WRPROTECT + static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep) + { + pte_t old_pte, pte; + +- /* +- * ptep_set_wrprotect() is only called on CoW mappings which are +- * private (!VM_SHARED) with the pte either read-only (!PTE_WRITE && +- * PTE_RDONLY) or writable and software-dirty (PTE_WRITE && +- * !PTE_RDONLY && PTE_DIRTY); see is_cow_mapping() and +- * protection_map[]. There is no race with the hardware update of the +- * dirty state: clearing of PTE_RDONLY when PTE_WRITE (a.k.a. PTE_DBM) +- * is set. +- */ +- VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(*ptep), +- "%s: potential race with hardware DBM", __func__); + pte = READ_ONCE(*ptep); + do { + old_pte = pte; ++ /* ++ * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY ++ * clear), set the PTE_DIRTY bit. ++ */ ++ if (pte_hw_dirty(pte)) ++ pte = pte_mkdirty(pte); + pte = pte_wrprotect(pte); + pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), + pte_val(old_pte), pte_val(pte)); diff --git a/queue-4.14/autofs-fix-careless-error-in-recent-commit.patch b/queue-4.14/autofs-fix-careless-error-in-recent-commit.patch new file mode 100644 index 00000000000..e6303512889 --- /dev/null +++ b/queue-4.14/autofs-fix-careless-error-in-recent-commit.patch @@ -0,0 +1,36 @@ +From 302ec300ef8a545a7fc7f667e5fd743b091c2eeb Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 14 Dec 2017 15:32:38 -0800 +Subject: autofs: fix careless error in recent commit + +From: NeilBrown + +commit 302ec300ef8a545a7fc7f667e5fd743b091c2eeb upstream. + +Commit ecc0c469f277 ("autofs: don't fail mount for transient error") was +meant to replace an 'if' with a 'switch', but instead added the 'switch' +leaving the case in place. + +Link: http://lkml.kernel.org/r/87zi6wstmw.fsf@notabene.neil.brown.name +Fixes: ecc0c469f277 ("autofs: don't fail mount for transient error") +Reported-by: Ben Hutchings +Signed-off-by: NeilBrown +Cc: Ian Kent +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/autofs4/waitq.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/autofs4/waitq.c ++++ b/fs/autofs4/waitq.c +@@ -170,7 +170,6 @@ static void autofs4_notify_daemon(struct + + mutex_unlock(&sbi->wq_mutex); + +- if (autofs4_write(sbi, pipe, &pkt, pktsz)) + switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) { + case 0: + break; diff --git a/queue-4.14/ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch b/queue-4.14/ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch new file mode 100644 index 00000000000..93c7ae58ce3 --- /dev/null +++ b/queue-4.14/ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch @@ -0,0 +1,85 @@ +From 040d786032bf59002d374b86d75b04d97624005c Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" +Date: Thu, 30 Nov 2017 11:59:22 +0800 +Subject: ceph: drop negative child dentries before try pruning inode's alias + +From: Yan, Zheng + +commit 040d786032bf59002d374b86d75b04d97624005c upstream. + +Negative child dentry holds reference on inode's alias, it makes +d_prune_aliases() do nothing. + +Signed-off-by: "Yan, Zheng" +Reviewed-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/mds_client.c | 42 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 38 insertions(+), 4 deletions(-) + +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -1428,6 +1428,29 @@ static int __close_session(struct ceph_m + return request_close_session(mdsc, session); + } + ++static bool drop_negative_children(struct dentry *dentry) ++{ ++ struct dentry *child; ++ bool all_negative = true; ++ ++ if (!d_is_dir(dentry)) ++ goto out; ++ ++ spin_lock(&dentry->d_lock); ++ list_for_each_entry(child, &dentry->d_subdirs, d_child) { ++ if (d_really_is_positive(child)) { ++ all_negative = false; ++ break; ++ } ++ } ++ spin_unlock(&dentry->d_lock); ++ ++ if (all_negative) ++ shrink_dcache_parent(dentry); ++out: ++ return all_negative; ++} ++ + /* + * Trim old(er) caps. + * +@@ -1473,16 +1496,27 @@ static int trim_caps_cb(struct inode *in + if ((used | wanted) & ~oissued & mine) + goto out; /* we need these caps */ + +- session->s_trim_caps--; + if (oissued) { + /* we aren't the only cap.. just remove us */ + __ceph_remove_cap(cap, true); ++ session->s_trim_caps--; + } else { ++ struct dentry *dentry; + /* try dropping referring dentries */ + spin_unlock(&ci->i_ceph_lock); +- d_prune_aliases(inode); +- dout("trim_caps_cb %p cap %p pruned, count now %d\n", +- inode, cap, atomic_read(&inode->i_count)); ++ dentry = d_find_any_alias(inode); ++ if (dentry && drop_negative_children(dentry)) { ++ int count; ++ dput(dentry); ++ d_prune_aliases(inode); ++ count = atomic_read(&inode->i_count); ++ if (count == 1) ++ session->s_trim_caps--; ++ dout("trim_caps_cb %p cap %p pruned, count now %d\n", ++ inode, cap, count); ++ } else { ++ dput(dentry); ++ } + return 0; + } + diff --git a/queue-4.14/dm-fix-various-targets-to-dm_register_target-after-module-__init-resources-created.patch b/queue-4.14/dm-fix-various-targets-to-dm_register_target-after-module-__init-resources-created.patch new file mode 100644 index 00000000000..025ab5c87cc --- /dev/null +++ b/queue-4.14/dm-fix-various-targets-to-dm_register_target-after-module-__init-resources-created.patch @@ -0,0 +1,250 @@ +From 7e6358d244e4706fe612a77b9c36519a33600ac0 Mon Sep 17 00:00:00 2001 +From: "monty_pavel@sina.com" +Date: Sat, 25 Nov 2017 01:43:50 +0800 +Subject: dm: fix various targets to dm_register_target after module __init resources created + +From: monty_pavel@sina.com + +commit 7e6358d244e4706fe612a77b9c36519a33600ac0 upstream. + +A NULL pointer is seen if two concurrent "vgchange -ay -K " +processes race to load the dm-thin-pool module: + + PID: 25992 TASK: ffff883cd7d23500 CPU: 4 COMMAND: "vgchange" + #0 [ffff883cd743d600] machine_kexec at ffffffff81038fa9 + 0000001 [ffff883cd743d660] crash_kexec at ffffffff810c5992 + 0000002 [ffff883cd743d730] oops_end at ffffffff81515c90 + 0000003 [ffff883cd743d760] no_context at ffffffff81049f1b + 0000004 [ffff883cd743d7b0] __bad_area_nosemaphore at ffffffff8104a1a5 + 0000005 [ffff883cd743d800] bad_area at ffffffff8104a2ce + 0000006 [ffff883cd743d830] __do_page_fault at ffffffff8104aa6f + 0000007 [ffff883cd743d950] do_page_fault at ffffffff81517bae + 0000008 [ffff883cd743d980] page_fault at ffffffff81514f95 + [exception RIP: kmem_cache_alloc+108] + RIP: ffffffff8116ef3c RSP: ffff883cd743da38 RFLAGS: 00010046 + RAX: 0000000000000004 RBX: ffffffff81121b90 RCX: ffff881bf1e78cc0 + RDX: 0000000000000000 RSI: 00000000000000d0 RDI: 0000000000000000 + RBP: ffff883cd743da68 R8: ffff881bf1a4eb00 R9: 0000000080042000 + R10: 0000000000002000 R11: 0000000000000000 R12: 00000000000000d0 + R13: 0000000000000000 R14: 00000000000000d0 R15: 0000000000000246 + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 + 0000009 [ffff883cd743da70] mempool_alloc_slab at ffffffff81121ba5 + 0000010 [ffff883cd743da80] mempool_create_node at ffffffff81122083 + 0000011 [ffff883cd743dad0] mempool_create at ffffffff811220f4 + 0000012 [ffff883cd743dae0] pool_ctr at ffffffffa08de049 [dm_thin_pool] + 0000013 [ffff883cd743dbd0] dm_table_add_target at ffffffffa0005f2f [dm_mod] + 0000014 [ffff883cd743dc30] table_load at ffffffffa0008ba9 [dm_mod] + 0000015 [ffff883cd743dc90] ctl_ioctl at ffffffffa0009dc4 [dm_mod] + +The race results in a NULL pointer because: + +Process A (vgchange -ay -K): + a. send DM_LIST_VERSIONS_CMD ioctl; + b. pool_target not registered; + c. modprobe dm_thin_pool and wait until end. + +Process B (vgchange -ay -K): + a. send DM_LIST_VERSIONS_CMD ioctl; + b. pool_target registered; + c. table_load->dm_table_add_target->pool_ctr; + d. _new_mapping_cache is NULL and panic. +Note: + 1. process A and process B are two concurrent processes. + 2. pool_target can be detected by process B but + _new_mapping_cache initialization has not ended. + +To fix dm-thin-pool, and other targets (cache, multipath, and snapshot) +with the same problem, simply dm_register_target() after all resources +created during module init (as labelled with __init) are finished. + +Signed-off-by: monty +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-cache-target.c | 12 +++++----- + drivers/md/dm-mpath.c | 18 ++++++++-------- + drivers/md/dm-snap.c | 48 +++++++++++++++++++++---------------------- + drivers/md/dm-thin.c | 22 ++++++++----------- + 4 files changed, 49 insertions(+), 51 deletions(-) + +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -3554,18 +3554,18 @@ static int __init dm_cache_init(void) + { + int r; + +- r = dm_register_target(&cache_target); +- if (r) { +- DMERR("cache target registration failed: %d", r); +- return r; +- } +- + migration_cache = KMEM_CACHE(dm_cache_migration, 0); + if (!migration_cache) { + dm_unregister_target(&cache_target); + return -ENOMEM; + } + ++ r = dm_register_target(&cache_target); ++ if (r) { ++ DMERR("cache target registration failed: %d", r); ++ return r; ++ } ++ + return 0; + } + +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1965,13 +1965,6 @@ static int __init dm_multipath_init(void + { + int r; + +- r = dm_register_target(&multipath_target); +- if (r < 0) { +- DMERR("request-based register failed %d", r); +- r = -EINVAL; +- goto bad_register_target; +- } +- + kmultipathd = alloc_workqueue("kmpathd", WQ_MEM_RECLAIM, 0); + if (!kmultipathd) { + DMERR("failed to create workqueue kmpathd"); +@@ -1993,13 +1986,20 @@ static int __init dm_multipath_init(void + goto bad_alloc_kmpath_handlerd; + } + ++ r = dm_register_target(&multipath_target); ++ if (r < 0) { ++ DMERR("request-based register failed %d", r); ++ r = -EINVAL; ++ goto bad_register_target; ++ } ++ + return 0; + ++bad_register_target: ++ destroy_workqueue(kmpath_handlerd); + bad_alloc_kmpath_handlerd: + destroy_workqueue(kmultipathd); + bad_alloc_kmultipathd: +- dm_unregister_target(&multipath_target); +-bad_register_target: + return r; + } + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -2411,24 +2411,6 @@ static int __init dm_snapshot_init(void) + return r; + } + +- r = dm_register_target(&snapshot_target); +- if (r < 0) { +- DMERR("snapshot target register failed %d", r); +- goto bad_register_snapshot_target; +- } +- +- r = dm_register_target(&origin_target); +- if (r < 0) { +- DMERR("Origin target register failed %d", r); +- goto bad_register_origin_target; +- } +- +- r = dm_register_target(&merge_target); +- if (r < 0) { +- DMERR("Merge target register failed %d", r); +- goto bad_register_merge_target; +- } +- + r = init_origin_hash(); + if (r) { + DMERR("init_origin_hash failed."); +@@ -2449,19 +2431,37 @@ static int __init dm_snapshot_init(void) + goto bad_pending_cache; + } + ++ r = dm_register_target(&snapshot_target); ++ if (r < 0) { ++ DMERR("snapshot target register failed %d", r); ++ goto bad_register_snapshot_target; ++ } ++ ++ r = dm_register_target(&origin_target); ++ if (r < 0) { ++ DMERR("Origin target register failed %d", r); ++ goto bad_register_origin_target; ++ } ++ ++ r = dm_register_target(&merge_target); ++ if (r < 0) { ++ DMERR("Merge target register failed %d", r); ++ goto bad_register_merge_target; ++ } ++ + return 0; + +-bad_pending_cache: +- kmem_cache_destroy(exception_cache); +-bad_exception_cache: +- exit_origin_hash(); +-bad_origin_hash: +- dm_unregister_target(&merge_target); + bad_register_merge_target: + dm_unregister_target(&origin_target); + bad_register_origin_target: + dm_unregister_target(&snapshot_target); + bad_register_snapshot_target: ++ kmem_cache_destroy(pending_cache); ++bad_pending_cache: ++ kmem_cache_destroy(exception_cache); ++bad_exception_cache: ++ exit_origin_hash(); ++bad_origin_hash: + dm_exception_store_exit(); + + return r; +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -4355,30 +4355,28 @@ static struct target_type thin_target = + + static int __init dm_thin_init(void) + { +- int r; ++ int r = -ENOMEM; + + pool_table_init(); + ++ _new_mapping_cache = KMEM_CACHE(dm_thin_new_mapping, 0); ++ if (!_new_mapping_cache) ++ return r; ++ + r = dm_register_target(&thin_target); + if (r) +- return r; ++ goto bad_new_mapping_cache; + + r = dm_register_target(&pool_target); + if (r) +- goto bad_pool_target; +- +- r = -ENOMEM; +- +- _new_mapping_cache = KMEM_CACHE(dm_thin_new_mapping, 0); +- if (!_new_mapping_cache) +- goto bad_new_mapping_cache; ++ goto bad_thin_target; + + return 0; + +-bad_new_mapping_cache: +- dm_unregister_target(&pool_target); +-bad_pool_target: ++bad_thin_target: + dm_unregister_target(&thin_target); ++bad_new_mapping_cache: ++ kmem_cache_destroy(_new_mapping_cache); + + return r; + } diff --git a/queue-4.14/dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch b/queue-4.14/dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch new file mode 100644 index 00000000000..41d6f236f08 --- /dev/null +++ b/queue-4.14/dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch @@ -0,0 +1,159 @@ +From 6f6a23a213be51728502b88741ba6a10cda2441d Mon Sep 17 00:00:00 2001 +From: Adam Wallis +Date: Mon, 27 Nov 2017 10:45:01 -0500 +Subject: dmaengine: dmatest: move callback wait queue to thread context + +From: Adam Wallis + +commit 6f6a23a213be51728502b88741ba6a10cda2441d upstream. + +Commit adfa543e7314 ("dmatest: don't use set_freezable_with_signal()") +introduced a bug (that is in fact documented by the patch commit text) +that leaves behind a dangling pointer. Since the done_wait structure is +allocated on the stack, future invocations to the DMATEST can produce +undesirable results (e.g., corrupted spinlocks). + +Commit a9df21e34b42 ("dmaengine: dmatest: warn user when dma test times +out") attempted to WARN the user that the stack was likely corrupted but +did not fix the actual issue. + +This patch fixes the issue by pushing the wait queue and callback +structs into the the thread structure. If a failure occurs due to time, +dmaengine_terminate_all will force the callback to safely call +wake_up_all() without possibility of using a freed pointer. + +Bug: https://bugzilla.kernel.org/show_bug.cgi?id=197605 +Fixes: adfa543e7314 ("dmatest: don't use set_freezable_with_signal()") +Reviewed-by: Sinan Kaya +Suggested-by: Shunyong Yang +Signed-off-by: Adam Wallis +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/dmatest.c | 55 ++++++++++++++++++++++++++++---------------------- + 1 file changed, 31 insertions(+), 24 deletions(-) + +--- a/drivers/dma/dmatest.c ++++ b/drivers/dma/dmatest.c +@@ -155,6 +155,12 @@ MODULE_PARM_DESC(run, "Run the test (def + #define PATTERN_COUNT_MASK 0x1f + #define PATTERN_MEMSET_IDX 0x01 + ++/* poor man's completion - we want to use wait_event_freezable() on it */ ++struct dmatest_done { ++ bool done; ++ wait_queue_head_t *wait; ++}; ++ + struct dmatest_thread { + struct list_head node; + struct dmatest_info *info; +@@ -165,6 +171,8 @@ struct dmatest_thread { + u8 **dsts; + u8 **udsts; + enum dma_transaction_type type; ++ wait_queue_head_t done_wait; ++ struct dmatest_done test_done; + bool done; + }; + +@@ -342,18 +350,25 @@ static unsigned int dmatest_verify(u8 ** + return error_count; + } + +-/* poor man's completion - we want to use wait_event_freezable() on it */ +-struct dmatest_done { +- bool done; +- wait_queue_head_t *wait; +-}; + + static void dmatest_callback(void *arg) + { + struct dmatest_done *done = arg; +- +- done->done = true; +- wake_up_all(done->wait); ++ struct dmatest_thread *thread = ++ container_of(arg, struct dmatest_thread, done_wait); ++ if (!thread->done) { ++ done->done = true; ++ wake_up_all(done->wait); ++ } else { ++ /* ++ * If thread->done, it means that this callback occurred ++ * after the parent thread has cleaned up. This can ++ * happen in the case that driver doesn't implement ++ * the terminate_all() functionality and a dma operation ++ * did not occur within the timeout period ++ */ ++ WARN(1, "dmatest: Kernel memory may be corrupted!!\n"); ++ } + } + + static unsigned int min_odd(unsigned int x, unsigned int y) +@@ -424,9 +439,8 @@ static unsigned long long dmatest_KBs(s6 + */ + static int dmatest_func(void *data) + { +- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait); + struct dmatest_thread *thread = data; +- struct dmatest_done done = { .wait = &done_wait }; ++ struct dmatest_done *done = &thread->test_done; + struct dmatest_info *info; + struct dmatest_params *params; + struct dma_chan *chan; +@@ -673,9 +687,9 @@ static int dmatest_func(void *data) + continue; + } + +- done.done = false; ++ done->done = false; + tx->callback = dmatest_callback; +- tx->callback_param = &done; ++ tx->callback_param = done; + cookie = tx->tx_submit(tx); + + if (dma_submit_error(cookie)) { +@@ -688,21 +702,12 @@ static int dmatest_func(void *data) + } + dma_async_issue_pending(chan); + +- wait_event_freezable_timeout(done_wait, done.done, ++ wait_event_freezable_timeout(thread->done_wait, done->done, + msecs_to_jiffies(params->timeout)); + + status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); + +- if (!done.done) { +- /* +- * We're leaving the timed out dma operation with +- * dangling pointer to done_wait. To make this +- * correct, we'll need to allocate wait_done for +- * each test iteration and perform "who's gonna +- * free it this time?" dancing. For now, just +- * leave it dangling. +- */ +- WARN(1, "dmatest: Kernel stack may be corrupted!!\n"); ++ if (!done->done) { + dmaengine_unmap_put(um); + result("test timed out", total_tests, src_off, dst_off, + len, 0); +@@ -789,7 +794,7 @@ err_thread_type: + dmatest_KBs(runtime, total_len), ret); + + /* terminate all transfers on specified channels */ +- if (ret) ++ if (ret || failed_tests) + dmaengine_terminate_all(chan); + + thread->done = true; +@@ -849,6 +854,8 @@ static int dmatest_add_threads(struct dm + thread->info = info; + thread->chan = dtc->chan; + thread->type = type; ++ thread->test_done.wait = &thread->done_wait; ++ init_waitqueue_head(&thread->done_wait); + smp_wmb(); + thread->task = kthread_create(dmatest_func, thread, "%s-%s%u", + dma_chan_name(chan), op, i); diff --git a/queue-4.14/eeprom-at24-change-nvmem-stride-to-1.patch b/queue-4.14/eeprom-at24-change-nvmem-stride-to-1.patch new file mode 100644 index 00000000000..a447b5d8c4e --- /dev/null +++ b/queue-4.14/eeprom-at24-change-nvmem-stride-to-1.patch @@ -0,0 +1,34 @@ +From 7f6d2ecd3d7acaf205ea7b3e96f9ffc55b92298b Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Sun, 3 Dec 2017 19:54:41 -0600 +Subject: eeprom: at24: change nvmem stride to 1 + +From: David Lechner + +commit 7f6d2ecd3d7acaf205ea7b3e96f9ffc55b92298b upstream. + +Trying to read the MAC address from an eeprom that has an offset that +is not a multiple of 4 causes an error currently. + +Fix it by changing the nvmem stride to 1. + +Signed-off-by: David Lechner +[Bartosz: tweaked the commit message] +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/eeprom/at24.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/eeprom/at24.c ++++ b/drivers/misc/eeprom/at24.c +@@ -776,7 +776,7 @@ static int at24_probe(struct i2c_client + at24->nvmem_config.reg_read = at24_read; + at24->nvmem_config.reg_write = at24_write; + at24->nvmem_config.priv = at24; +- at24->nvmem_config.stride = 4; ++ at24->nvmem_config.stride = 1; + at24->nvmem_config.word_size = 1; + at24->nvmem_config.size = chip.byte_len; + diff --git a/queue-4.14/ext4-add-missing-error-check-in-__ext4_new_inode.patch b/queue-4.14/ext4-add-missing-error-check-in-__ext4_new_inode.patch new file mode 100644 index 00000000000..aac8cec8295 --- /dev/null +++ b/queue-4.14/ext4-add-missing-error-check-in-__ext4_new_inode.patch @@ -0,0 +1,34 @@ +From 996fc4477a0ea28226b30d175f053fb6f9a4fa36 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 10 Dec 2017 23:44:11 -0500 +Subject: ext4: add missing error check in __ext4_new_inode() + +From: Theodore Ts'o + +commit 996fc4477a0ea28226b30d175f053fb6f9a4fa36 upstream. + +It's possible for ext4_get_acl() to return an ERR_PTR. So we need to +add a check for this case in __ext4_new_inode(). Otherwise on an +error we can end up oops the kernel. + +This was getting triggered by xfstests generic/388, which is a test +which exercises the shutdown code path. + +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ialloc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -816,6 +816,8 @@ struct inode *__ext4_new_inode(handle_t + #ifdef CONFIG_EXT4_FS_POSIX_ACL + struct posix_acl *p = get_acl(dir, ACL_TYPE_DEFAULT); + ++ if (IS_ERR(p)) ++ return ERR_CAST(p); + if (p) { + int acl_size = p->a_count * sizeof(ext4_acl_entry); + diff --git a/queue-4.14/ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch b/queue-4.14/ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch new file mode 100644 index 00000000000..59a26f34cf4 --- /dev/null +++ b/queue-4.14/ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch @@ -0,0 +1,57 @@ +From 9d5afec6b8bd46d6ed821aa1579634437f58ef1f Mon Sep 17 00:00:00 2001 +From: Chandan Rajendra +Date: Mon, 11 Dec 2017 15:00:57 -0500 +Subject: ext4: fix crash when a directory's i_size is too small + +From: Chandan Rajendra + +commit 9d5afec6b8bd46d6ed821aa1579634437f58ef1f upstream. + +On a ppc64 machine, when mounting a fuzzed ext2 image (generated by +fsfuzzer) the following call trace is seen, + +VFS: brelse: Trying to free free buffer +WARNING: CPU: 1 PID: 6913 at /root/repos/linux/fs/buffer.c:1165 .__brelse.part.6+0x24/0x40 +.__brelse.part.6+0x20/0x40 (unreliable) +.ext4_find_entry+0x384/0x4f0 +.ext4_lookup+0x84/0x250 +.lookup_slow+0xdc/0x230 +.walk_component+0x268/0x400 +.path_lookupat+0xec/0x2d0 +.filename_lookup+0x9c/0x1d0 +.vfs_statx+0x98/0x140 +.SyS_newfstatat+0x48/0x80 +system_call+0x58/0x6c + +This happens because the directory that ext4_find_entry() looks up has +inode->i_size that is less than the block size of the filesystem. This +causes 'nblocks' to have a value of zero. ext4_bread_batch() ends up not +reading any of the directory file's blocks. This renders the entries in +bh_use[] array to continue to have garbage data. buffer_uptodate() on +bh_use[0] can then return a zero value upon which brelse() function is +invoked. + +This commit fixes the bug by returning -ENOENT when the directory file +has no associated blocks. + +Reported-by: Abdul Haleem +Signed-off-by: Chandan Rajendra +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/namei.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -1399,6 +1399,10 @@ static struct buffer_head * ext4_find_en + "falling back\n")); + } + nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); ++ if (!nblocks) { ++ ret = NULL; ++ goto cleanup_and_exit; ++ } + start = EXT4_I(dir)->i_dir_start_lookup; + if (start >= nblocks) + start = 0; diff --git a/queue-4.14/ext4-fix-fdatasync-2-after-fallocate-2-operation.patch b/queue-4.14/ext4-fix-fdatasync-2-after-fallocate-2-operation.patch new file mode 100644 index 00000000000..34c13f1bedc --- /dev/null +++ b/queue-4.14/ext4-fix-fdatasync-2-after-fallocate-2-operation.patch @@ -0,0 +1,43 @@ +From c894aa97577e47d3066b27b32499ecf899bfa8b0 Mon Sep 17 00:00:00 2001 +From: Eryu Guan +Date: Sun, 3 Dec 2017 22:52:51 -0500 +Subject: ext4: fix fdatasync(2) after fallocate(2) operation + +From: Eryu Guan + +commit c894aa97577e47d3066b27b32499ecf899bfa8b0 upstream. + +Currently, fallocate(2) with KEEP_SIZE followed by a fdatasync(2) +then crash, we'll see wrong allocated block number (stat -c %b), the +blocks allocated beyond EOF are all lost. fstests generic/468 +exposes this bug. + +Commit 67a7d5f561f4 ("ext4: fix fdatasync(2) after extent +manipulation operations") fixed all the other extent manipulation +operation paths such as hole punch, zero range, collapse range etc., +but forgot the fallocate case. + +So similarly, fix it by recording the correct journal tid in ext4 +inode in fallocate(2) path, so that ext4_sync_file() will wait for +the right tid to be committed on fdatasync(2). + +This addresses the test failure in xfstests test generic/468. + +Signed-off-by: Eryu Guan +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/extents.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4722,6 +4722,7 @@ retry: + EXT4_INODE_EOFBLOCKS); + } + ext4_mark_inode_dirty(handle, inode); ++ ext4_update_inode_fsync_trans(handle, inode, 1); + ret2 = ext4_journal_stop(handle); + if (ret2) + break; diff --git a/queue-4.14/ext4-support-fast-symlinks-from-ext3-file-systems.patch b/queue-4.14/ext4-support-fast-symlinks-from-ext3-file-systems.patch new file mode 100644 index 00000000000..1501e5a3558 --- /dev/null +++ b/queue-4.14/ext4-support-fast-symlinks-from-ext3-file-systems.patch @@ -0,0 +1,52 @@ +From fc82228a5e3860502dbf3bfa4a9570cb7093cf7f Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Sun, 3 Dec 2017 20:38:01 -0500 +Subject: ext4: support fast symlinks from ext3 file systems + +From: Andi Kleen + +commit fc82228a5e3860502dbf3bfa4a9570cb7093cf7f upstream. + +407cd7fb83c0 (ext4: change fast symlink test to not rely on i_blocks) +broke ~10 years old ext3 file systems created by 2.6.17. Any ELF +executable fails because the /lib/ld-linux.so.2 fast symlink +cannot be read anymore. + +The patch assumed fast symlinks were created in a specific way, +but that's not true on these really old file systems. + +The new behavior is apparently needed only with the large EA inode +feature. + +Revert to the old behavior if the large EA inode feature is not set. + +This makes my old VM boot again. + +Fixes: 407cd7fb83c0 (ext4: change fast symlink test to not rely on i_blocks) +Signed-off-by: Andi Kleen +Signed-off-by: Theodore Ts'o +Reviewed-by: Andreas Dilger +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -149,6 +149,15 @@ static int ext4_meta_trans_blocks(struct + */ + int ext4_inode_is_fast_symlink(struct inode *inode) + { ++ if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) { ++ int ea_blocks = EXT4_I(inode)->i_file_acl ? ++ EXT4_CLUSTER_SIZE(inode->i_sb) >> 9 : 0; ++ ++ if (ext4_has_inline_data(inode)) ++ return 0; ++ ++ return (S_ISLNK(inode->i_mode) && inode->i_blocks - ea_blocks == 0); ++ } + return S_ISLNK(inode->i_mode) && inode->i_size && + (inode->i_size < EXT4_N_BLOCKS * 4); + } diff --git a/queue-4.14/ib-core-bound-check-alternate-path-port-number.patch b/queue-4.14/ib-core-bound-check-alternate-path-port-number.patch new file mode 100644 index 00000000000..c0bda445312 --- /dev/null +++ b/queue-4.14/ib-core-bound-check-alternate-path-port-number.patch @@ -0,0 +1,38 @@ +From 4cae8ff136782d77b108cb3a5ba53e60597ba3a6 Mon Sep 17 00:00:00 2001 +From: Daniel Jurgens +Date: Tue, 5 Dec 2017 22:30:01 +0200 +Subject: IB/core: Bound check alternate path port number + +From: Daniel Jurgens + +commit 4cae8ff136782d77b108cb3a5ba53e60597ba3a6 upstream. + +The alternate port number is used as an array index in the IB +security implementation, invalid values can result in a kernel panic. + +Fixes: d291f1a65232 ("IB/core: Enforce PKey security on QPs") +Signed-off-by: Daniel Jurgens +Reviewed-by: Parav Pandit +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_cmd.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -1982,6 +1982,12 @@ static int modify_qp(struct ib_uverbs_fi + goto release_qp; + } + ++ if ((cmd->base.attr_mask & IB_QP_ALT_PATH) && ++ !rdma_is_port_valid(qp->device, cmd->base.alt_port_num)) { ++ ret = -EINVAL; ++ goto release_qp; ++ } ++ + attr->qp_state = cmd->base.qp_state; + attr->cur_qp_state = cmd->base.cur_qp_state; + attr->path_mtu = cmd->base.path_mtu; diff --git a/queue-4.14/ib-core-don-t-enforce-pkey-security-on-smi-mads.patch b/queue-4.14/ib-core-don-t-enforce-pkey-security-on-smi-mads.patch new file mode 100644 index 00000000000..a8927ade1ff --- /dev/null +++ b/queue-4.14/ib-core-don-t-enforce-pkey-security-on-smi-mads.patch @@ -0,0 +1,45 @@ +From 0fbe8f575b15585eec3326e43708fbbc024e8486 Mon Sep 17 00:00:00 2001 +From: Daniel Jurgens +Date: Tue, 5 Dec 2017 22:30:02 +0200 +Subject: IB/core: Don't enforce PKey security on SMI MADs + +From: Daniel Jurgens + +commit 0fbe8f575b15585eec3326e43708fbbc024e8486 upstream. + +Per the infiniband spec an SMI MAD can have any PKey. Checking the pkey +on SMI MADs is not necessary, and it seems that some older adapters +using the mthca driver don't follow the convention of using the default +PKey, resulting in false denials, or errors querying the PKey cache. + +SMI MAD security is still enforced, only agents allowed to manage the +subnet are able to receive or send SMI MADs. + +Reported-by: Chris Blake +Fixes: 47a2b338fe63 ("IB/core: Enforce security on management datagrams") +Signed-off-by: Daniel Jurgens +Reviewed-by: Parav Pandit +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/security.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/core/security.c ++++ b/drivers/infiniband/core/security.c +@@ -739,8 +739,11 @@ int ib_mad_enforce_security(struct ib_ma + if (!rdma_protocol_ib(map->agent.device, map->agent.port_num)) + return 0; + +- if (map->agent.qp->qp_type == IB_QPT_SMI && !map->agent.smp_allowed) +- return -EACCES; ++ if (map->agent.qp->qp_type == IB_QPT_SMI) { ++ if (!map->agent.smp_allowed) ++ return -EACCES; ++ return 0; ++ } + + return ib_security_pkey_access(map->agent.device, + map->agent.port_num, diff --git a/queue-4.14/iw_cxgb4-only-insert-drain-cqes-if-wq-is-flushed.patch b/queue-4.14/iw_cxgb4-only-insert-drain-cqes-if-wq-is-flushed.patch new file mode 100644 index 00000000000..76a31952c06 --- /dev/null +++ b/queue-4.14/iw_cxgb4-only-insert-drain-cqes-if-wq-is-flushed.patch @@ -0,0 +1,75 @@ +From c058ecf6e455fac7346d46197a02398ead90851f Mon Sep 17 00:00:00 2001 +From: Steve Wise +Date: Mon, 27 Nov 2017 13:16:32 -0800 +Subject: iw_cxgb4: only insert drain cqes if wq is flushed + +From: Steve Wise + +commit c058ecf6e455fac7346d46197a02398ead90851f upstream. + +Only insert our special drain CQEs to support ib_drain_sq/rq() after +the wq is flushed. Otherwise, existing but not yet polled CQEs can be +returned out of order to the user application. This can happen when the +QP has exited RTS but not yet flushed the QP, which can happen during +a normal close (vs abortive close). + +In addition never count the drain CQEs when determining how many CQEs +need to be synthesized during the flush operation. This latter issue +should never happen if the QP is properly flushed before inserting the +drain CQE, but I wanted to avoid corrupting the CQ state. So we handle +it and log a warning once. + +Fixes: 4fe7c2962e11 ("iw_cxgb4: refactor sq/rq drain logic") +Signed-off-by: Steve Wise +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/cxgb4/cq.c | 5 +++++ + drivers/infiniband/hw/cxgb4/qp.c | 14 ++++++++++++-- + 2 files changed, 17 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/cxgb4/cq.c ++++ b/drivers/infiniband/hw/cxgb4/cq.c +@@ -410,6 +410,11 @@ next_cqe: + + static int cqe_completes_wr(struct t4_cqe *cqe, struct t4_wq *wq) + { ++ if (CQE_OPCODE(cqe) == C4IW_DRAIN_OPCODE) { ++ WARN_ONCE(1, "Unexpected DRAIN CQE qp id %u!\n", wq->sq.qid); ++ return 0; ++ } ++ + if (CQE_OPCODE(cqe) == FW_RI_TERMINATE) + return 0; + +--- a/drivers/infiniband/hw/cxgb4/qp.c ++++ b/drivers/infiniband/hw/cxgb4/qp.c +@@ -868,7 +868,12 @@ int c4iw_post_send(struct ib_qp *ibqp, s + + qhp = to_c4iw_qp(ibqp); + spin_lock_irqsave(&qhp->lock, flag); +- if (t4_wq_in_error(&qhp->wq)) { ++ ++ /* ++ * If the qp has been flushed, then just insert a special ++ * drain cqe. ++ */ ++ if (qhp->wq.flushed) { + spin_unlock_irqrestore(&qhp->lock, flag); + complete_sq_drain_wr(qhp, wr); + return err; +@@ -1012,7 +1017,12 @@ int c4iw_post_receive(struct ib_qp *ibqp + + qhp = to_c4iw_qp(ibqp); + spin_lock_irqsave(&qhp->lock, flag); +- if (t4_wq_in_error(&qhp->wq)) { ++ ++ /* ++ * If the qp has been flushed, then just insert a special ++ * drain cqe. ++ */ ++ if (qhp->wq.flushed) { + spin_unlock_irqrestore(&qhp->lock, flag); + complete_rq_drain_wr(qhp, wr); + return err; diff --git a/queue-4.14/kernel-make-groups_sort-calling-a-responsibility-group_info-allocators.patch b/queue-4.14/kernel-make-groups_sort-calling-a-responsibility-group_info-allocators.patch new file mode 100644 index 00000000000..6de88075c1a --- /dev/null +++ b/queue-4.14/kernel-make-groups_sort-calling-a-responsibility-group_info-allocators.patch @@ -0,0 +1,153 @@ +From bdcf0a423ea1c40bbb40e7ee483b50fc8aa3d758 Mon Sep 17 00:00:00 2001 +From: Thiago Rafael Becker +Date: Thu, 14 Dec 2017 15:33:12 -0800 +Subject: kernel: make groups_sort calling a responsibility group_info allocators + +From: Thiago Rafael Becker + +commit bdcf0a423ea1c40bbb40e7ee483b50fc8aa3d758 upstream. + +In testing, we found that nfsd threads may call set_groups in parallel +for the same entry cached in auth.unix.gid, racing in the call of +groups_sort, corrupting the groups for that entry and leading to +permission denials for the client. + +This patch: + - Make groups_sort globally visible. + - Move the call to groups_sort to the modifiers of group_info + - Remove the call to groups_sort from set_groups + +Link: http://lkml.kernel.org/r/20171211151420.18655-1-thiago.becker@gmail.com +Signed-off-by: Thiago Rafael Becker +Reviewed-by: Matthew Wilcox +Reviewed-by: NeilBrown +Acked-by: "J. Bruce Fields" +Cc: Al Viro +Cc: Martin Schwidefsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/kernel/compat_linux.c | 1 + + fs/nfsd/auth.c | 3 +++ + include/linux/cred.h | 1 + + kernel/groups.c | 5 +++-- + kernel/uid16.c | 1 + + net/sunrpc/auth_gss/gss_rpc_xdr.c | 1 + + net/sunrpc/auth_gss/svcauth_gss.c | 1 + + net/sunrpc/svcauth_unix.c | 2 ++ + 8 files changed, 13 insertions(+), 2 deletions(-) + +--- a/arch/s390/kernel/compat_linux.c ++++ b/arch/s390/kernel/compat_linux.c +@@ -263,6 +263,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setgroups16, + return retval; + } + ++ groups_sort(group_info); + retval = set_current_groups(group_info); + put_group_info(group_info); + +--- a/fs/nfsd/auth.c ++++ b/fs/nfsd/auth.c +@@ -60,6 +60,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, + gi->gid[i] = exp->ex_anon_gid; + else + gi->gid[i] = rqgi->gid[i]; ++ ++ /* Each thread allocates its own gi, no race */ ++ groups_sort(gi); + } + } else { + gi = get_group_info(rqgi); +--- a/include/linux/cred.h ++++ b/include/linux/cred.h +@@ -83,6 +83,7 @@ extern int set_current_groups(struct gro + extern void set_groups(struct cred *, struct group_info *); + extern int groups_search(const struct group_info *, kgid_t); + extern bool may_setgroups(void); ++extern void groups_sort(struct group_info *); + + /* + * The security context of a task +--- a/kernel/groups.c ++++ b/kernel/groups.c +@@ -86,11 +86,12 @@ static int gid_cmp(const void *_a, const + return gid_gt(a, b) - gid_lt(a, b); + } + +-static void groups_sort(struct group_info *group_info) ++void groups_sort(struct group_info *group_info) + { + sort(group_info->gid, group_info->ngroups, sizeof(*group_info->gid), + gid_cmp, NULL); + } ++EXPORT_SYMBOL(groups_sort); + + /* a simple bsearch */ + int groups_search(const struct group_info *group_info, kgid_t grp) +@@ -122,7 +123,6 @@ int groups_search(const struct group_inf + void set_groups(struct cred *new, struct group_info *group_info) + { + put_group_info(new->group_info); +- groups_sort(group_info); + get_group_info(group_info); + new->group_info = group_info; + } +@@ -206,6 +206,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsi + return retval; + } + ++ groups_sort(group_info); + retval = set_current_groups(group_info); + put_group_info(group_info); + +--- a/kernel/uid16.c ++++ b/kernel/uid16.c +@@ -192,6 +192,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidset + return retval; + } + ++ groups_sort(group_info); + retval = set_current_groups(group_info); + put_group_info(group_info); + +--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c ++++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c +@@ -231,6 +231,7 @@ static int gssx_dec_linux_creds(struct x + goto out_free_groups; + creds->cr_group_info->gid[i] = kgid; + } ++ groups_sort(creds->cr_group_info); + + return 0; + out_free_groups: +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -481,6 +481,7 @@ static int rsc_parse(struct cache_detail + goto out; + rsci.cred.cr_group_info->gid[i] = kgid; + } ++ groups_sort(rsci.cred.cr_group_info); + + /* mech name */ + len = qword_get(&mesg, buf, mlen); +--- a/net/sunrpc/svcauth_unix.c ++++ b/net/sunrpc/svcauth_unix.c +@@ -520,6 +520,7 @@ static int unix_gid_parse(struct cache_d + ug.gi->gid[i] = kgid; + } + ++ groups_sort(ug.gi); + ugp = unix_gid_lookup(cd, uid); + if (ugp) { + struct cache_head *ch; +@@ -819,6 +820,7 @@ svcauth_unix_accept(struct svc_rqst *rqs + kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); + cred->cr_group_info->gid[i] = kgid; + } ++ groups_sort(cred->cr_group_info); + if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { + *authp = rpc_autherr_badverf; + return SVC_DENIED; diff --git a/queue-4.14/mm-oom_reaper-fix-memory-corruption.patch b/queue-4.14/mm-oom_reaper-fix-memory-corruption.patch new file mode 100644 index 00000000000..ecc15ff9920 --- /dev/null +++ b/queue-4.14/mm-oom_reaper-fix-memory-corruption.patch @@ -0,0 +1,137 @@ +From 4837fe37adff1d159904f0c013471b1ecbcb455e Mon Sep 17 00:00:00 2001 +From: Michal Hocko +Date: Thu, 14 Dec 2017 15:33:15 -0800 +Subject: mm, oom_reaper: fix memory corruption + +From: Michal Hocko + +commit 4837fe37adff1d159904f0c013471b1ecbcb455e upstream. + +David Rientjes has reported the following memory corruption while the +oom reaper tries to unmap the victims address space + + BUG: Bad page map in process oom_reaper pte:6353826300000000 pmd:00000000 + addr:00007f50cab1d000 vm_flags:08100073 anon_vma:ffff9eea335603f0 mapping: (null) index:7f50cab1d + file: (null) fault: (null) mmap: (null) readpage: (null) + CPU: 2 PID: 1001 Comm: oom_reaper + Call Trace: + unmap_page_range+0x1068/0x1130 + __oom_reap_task_mm+0xd5/0x16b + oom_reaper+0xff/0x14c + kthread+0xc1/0xe0 + +Tetsuo Handa has noticed that the synchronization inside exit_mmap is +insufficient. We only synchronize with the oom reaper if +tsk_is_oom_victim which is not true if the final __mmput is called from +a different context than the oom victim exit path. This can trivially +happen from context of any task which has grabbed mm reference (e.g. to +read /proc// file which requires mm etc.). + +The race would look like this + + oom_reaper oom_victim task + mmget_not_zero + do_exit + mmput + __oom_reap_task_mm mmput + __mmput + exit_mmap + remove_vma + unmap_page_range + +Fix this issue by providing a new mm_is_oom_victim() helper which +operates on the mm struct rather than a task. Any context which +operates on a remote mm struct should use this helper in place of +tsk_is_oom_victim. The flag is set in mark_oom_victim and never cleared +so it is stable in the exit_mmap path. + +Debugged by Tetsuo Handa. + +Link: http://lkml.kernel.org/r/20171210095130.17110-1-mhocko@kernel.org +Fixes: 212925802454 ("mm: oom: let oom_reap_task and exit_mmap run concurrently") +Signed-off-by: Michal Hocko +Reported-by: David Rientjes +Acked-by: David Rientjes +Cc: Tetsuo Handa +Cc: Andrea Argangeli +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/oom.h | 9 +++++++++ + include/linux/sched/coredump.h | 1 + + mm/mmap.c | 10 +++++----- + mm/oom_kill.c | 4 +++- + 4 files changed, 18 insertions(+), 6 deletions(-) + +--- a/include/linux/oom.h ++++ b/include/linux/oom.h +@@ -67,6 +67,15 @@ static inline bool tsk_is_oom_victim(str + } + + /* ++ * Use this helper if tsk->mm != mm and the victim mm needs a special ++ * handling. This is guaranteed to stay true after once set. ++ */ ++static inline bool mm_is_oom_victim(struct mm_struct *mm) ++{ ++ return test_bit(MMF_OOM_VICTIM, &mm->flags); ++} ++ ++/* + * Checks whether a page fault on the given mm is still reliable. + * This is no longer true if the oom reaper started to reap the + * address space which is reflected by MMF_UNSTABLE flag set in +--- a/include/linux/sched/coredump.h ++++ b/include/linux/sched/coredump.h +@@ -70,6 +70,7 @@ static inline int get_dumpable(struct mm + #define MMF_UNSTABLE 22 /* mm is unstable for copy_from_user */ + #define MMF_HUGE_ZERO_PAGE 23 /* mm has ever used the global huge zero page */ + #define MMF_DISABLE_THP 24 /* disable THP for all VMAs */ ++#define MMF_OOM_VICTIM 25 /* mm is the oom victim */ + #define MMF_DISABLE_THP_MASK (1 << MMF_DISABLE_THP) + + #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK |\ +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -3004,20 +3004,20 @@ void exit_mmap(struct mm_struct *mm) + /* Use -1 here to ensure all VMAs in the mm are unmapped */ + unmap_vmas(&tlb, vma, 0, -1); + +- set_bit(MMF_OOM_SKIP, &mm->flags); +- if (unlikely(tsk_is_oom_victim(current))) { ++ if (unlikely(mm_is_oom_victim(mm))) { + /* + * Wait for oom_reap_task() to stop working on this + * mm. Because MMF_OOM_SKIP is already set before + * calling down_read(), oom_reap_task() will not run + * on this "mm" post up_write(). + * +- * tsk_is_oom_victim() cannot be set from under us +- * either because current->mm is already set to NULL ++ * mm_is_oom_victim() cannot be set from under us ++ * either because victim->mm is already set to NULL + * under task_lock before calling mmput and oom_mm is +- * set not NULL by the OOM killer only if current->mm ++ * set not NULL by the OOM killer only if victim->mm + * is found not NULL while holding the task_lock. + */ ++ set_bit(MMF_OOM_SKIP, &mm->flags); + down_write(&mm->mmap_sem); + up_write(&mm->mmap_sem); + } +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -673,8 +673,10 @@ static void mark_oom_victim(struct task_ + return; + + /* oom_mm is bound to the signal struct life time. */ +- if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm)) ++ if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm)) { + mmgrab(tsk->signal->oom_mm); ++ set_bit(MMF_OOM_VICTIM, &mm->flags); ++ } + + /* + * Make sure that the task is woken up from uninterruptible sleep diff --git a/queue-4.14/mmc-core-apply-no_cmd23-quirk-to-some-specific-cards.patch b/queue-4.14/mmc-core-apply-no_cmd23-quirk-to-some-specific-cards.patch new file mode 100644 index 00000000000..b1348b2ff36 --- /dev/null +++ b/queue-4.14/mmc-core-apply-no_cmd23-quirk-to-some-specific-cards.patch @@ -0,0 +1,76 @@ +From 91516a2a4734614d62ee3ed921f8f88acc67c000 Mon Sep 17 00:00:00 2001 +From: Christoph Fritz +Date: Sat, 9 Dec 2017 23:47:55 +0100 +Subject: mmc: core: apply NO_CMD23 quirk to some specific cards + +From: Christoph Fritz + +commit 91516a2a4734614d62ee3ed921f8f88acc67c000 upstream. + +To get an usdhc Apacer and some ATP SD cards work reliable, CMD23 needs +to be disabled. This has been tested on i.MX6 (sdhci-esdhc) and rk3288 +(dw_mmc-rockchip). + +Without this patch on i.MX6 (sdhci-esdhc): + + $ dd if=/dev/urandom of=/mnt/test bs=1M count=10 conv=fsync + + | + | mmc0: starting CMD25 arg 00a71f00 flags 000000b5 + | mmc0: blksz 512 blocks 1024 flags 00000100 tsac 3000 ms nsac 0 + | mmc0: CMD12 arg 00000000 flags 0000049d + | sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000001 + | mmc0: Timeout waiting for hardware interrupt. + +Without this patch on rk3288 (dw_mmc-rockchip): + + | mmc1: Card stuck in programming state! mmcblk1 card_busy_detect + | dwmmc_rockchip ff0c0000.dwmmc: Busy; trying anyway + | mmc_host mmc1: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, + | actual 400000HZ div = 0) + | mmc1: card never left busy state + | mmc1: tried to reset card, got error -110 + | blk_update_request: I/O error, dev mmcblk1, sector 139778 + | Buffer I/O error on dev mmcblk1p1, logical block 131586, lost async + | page write + +Signed-off-by: Christoph Fritz +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/core/card.h | 2 ++ + drivers/mmc/core/quirks.h | 8 ++++++++ + 2 files changed, 10 insertions(+) + +--- a/drivers/mmc/core/card.h ++++ b/drivers/mmc/core/card.h +@@ -75,9 +75,11 @@ struct mmc_fixup { + #define EXT_CSD_REV_ANY (-1u) + + #define CID_MANFID_SANDISK 0x2 ++#define CID_MANFID_ATP 0x9 + #define CID_MANFID_TOSHIBA 0x11 + #define CID_MANFID_MICRON 0x13 + #define CID_MANFID_SAMSUNG 0x15 ++#define CID_MANFID_APACER 0x27 + #define CID_MANFID_KINGSTON 0x70 + #define CID_MANFID_HYNIX 0x90 + +--- a/drivers/mmc/core/quirks.h ++++ b/drivers/mmc/core/quirks.h +@@ -53,6 +53,14 @@ static const struct mmc_fixup mmc_blk_fi + MMC_QUIRK_BLK_NO_CMD23), + + /* ++ * Some SD cards lockup while using CMD23 multiblock transfers. ++ */ ++ MMC_FIXUP("AF SD", CID_MANFID_ATP, CID_OEMID_ANY, add_quirk_sd, ++ MMC_QUIRK_BLK_NO_CMD23), ++ MMC_FIXUP("APUSD", CID_MANFID_APACER, 0x5048, add_quirk_sd, ++ MMC_QUIRK_BLK_NO_CMD23), ++ ++ /* + * Some MMC cards need longer data read timeout than indicated in CSD. + */ + MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, diff --git a/queue-4.14/nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch b/queue-4.14/nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch new file mode 100644 index 00000000000..9815bc8bd3c --- /dev/null +++ b/queue-4.14/nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch @@ -0,0 +1,66 @@ +From dc4fd9ab01ab379ae5af522b3efd4187a7c30a31 Mon Sep 17 00:00:00 2001 +From: Scott Mayhew +Date: Fri, 8 Dec 2017 16:00:12 -0500 +Subject: nfs: don't wait on commit in nfs_commit_inode() if there were no commit requests + +From: Scott Mayhew + +commit dc4fd9ab01ab379ae5af522b3efd4187a7c30a31 upstream. + +If there were no commit requests, then nfs_commit_inode() should not +wait on the commit or mark the inode dirty, otherwise the following +BUG_ON can be triggered: + +[ 1917.130762] kernel BUG at fs/inode.c:578! +[ 1917.130766] Oops: Exception in kernel mode, sig: 5 [#1] +[ 1917.130768] SMP NR_CPUS=2048 NUMA pSeries +[ 1917.130772] Modules linked in: iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi blocklayoutdriver rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache sunrpc sg nx_crypto pseries_rng ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic crct10dif_common ibmvscsi scsi_transport_srp ibmveth scsi_tgt dm_mirror dm_region_hash dm_log dm_mod +[ 1917.130805] CPU: 2 PID: 14923 Comm: umount.nfs4 Tainted: G ------------ T 3.10.0-768.el7.ppc64 #1 +[ 1917.130810] task: c0000005ecd88040 ti: c00000004cea0000 task.ti: c00000004cea0000 +[ 1917.130813] NIP: c000000000354178 LR: c000000000354160 CTR: c00000000012db80 +[ 1917.130816] REGS: c00000004cea3720 TRAP: 0700 Tainted: G ------------ T (3.10.0-768.el7.ppc64) +[ 1917.130820] MSR: 8000000100029032 CR: 22002822 XER: 20000000 +[ 1917.130828] CFAR: c00000000011f594 SOFTE: 1 +GPR00: c000000000354160 c00000004cea39a0 c0000000014c4700 c0000000018cc750 +GPR04: 000000000000c750 80c0000000000000 0600000000000000 04eeb76bea749a03 +GPR08: 0000000000000034 c0000000018cc758 0000000000000001 d000000005e619e8 +GPR12: c00000000012db80 c000000007b31200 0000000000000000 0000000000000000 +GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 +GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 +GPR24: 0000000000000000 c000000000dfc3ec 0000000000000000 c0000005eefc02c0 +GPR28: d0000000079dbd50 c0000005b94a02c0 c0000005b94a0250 c0000005b94a01c8 +[ 1917.130867] NIP [c000000000354178] .evict+0x1c8/0x350 +[ 1917.130871] LR [c000000000354160] .evict+0x1b0/0x350 +[ 1917.130873] Call Trace: +[ 1917.130876] [c00000004cea39a0] [c000000000354160] .evict+0x1b0/0x350 (unreliable) +[ 1917.130880] [c00000004cea3a30] [c0000000003558cc] .evict_inodes+0x13c/0x270 +[ 1917.130884] [c00000004cea3af0] [c000000000327d20] .kill_anon_super+0x70/0x1e0 +[ 1917.130896] [c00000004cea3b80] [d000000005e43e30] .nfs_kill_super+0x20/0x60 [nfs] +[ 1917.130900] [c00000004cea3c00] [c000000000328a20] .deactivate_locked_super+0xa0/0x1b0 +[ 1917.130903] [c00000004cea3c80] [c00000000035ba54] .cleanup_mnt+0xd4/0x180 +[ 1917.130907] [c00000004cea3d10] [c000000000119034] .task_work_run+0x114/0x150 +[ 1917.130912] [c00000004cea3db0] [c00000000001ba6c] .do_notify_resume+0xcc/0x100 +[ 1917.130916] [c00000004cea3e30] [c00000000000a7b0] .ret_from_except_lite+0x5c/0x60 +[ 1917.130919] Instruction dump: +[ 1917.130921] 7fc3f378 486734b5 60000000 387f00a0 38800003 4bdcb365 60000000 e95f00a0 +[ 1917.130927] 694a0060 7d4a0074 794ad182 694a0001 <0b0a0000> 892d02a4 2f890000 40de0134 + +Signed-off-by: Scott Mayhew +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/write.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1889,6 +1889,8 @@ int nfs_commit_inode(struct inode *inode + if (res) + error = nfs_generic_commit_list(inode, &head, how, &cinfo); + nfs_commit_end(cinfo.mds); ++ if (res == 0) ++ return res; + if (error < 0) + goto out_error; + if (!may_wait) diff --git a/queue-4.14/ovl-pass-ovl_get_nlink-parameters-in-right-order.patch b/queue-4.14/ovl-pass-ovl_get_nlink-parameters-in-right-order.patch new file mode 100644 index 00000000000..d393e8b051f --- /dev/null +++ b/queue-4.14/ovl-pass-ovl_get_nlink-parameters-in-right-order.patch @@ -0,0 +1,34 @@ +From 08d8f8a5b094b66b29936e8751b4a818b8db1207 Mon Sep 17 00:00:00 2001 +From: Vivek Goyal +Date: Mon, 27 Nov 2017 10:12:44 -0500 +Subject: ovl: Pass ovl_get_nlink() parameters in right order + +From: Vivek Goyal + +commit 08d8f8a5b094b66b29936e8751b4a818b8db1207 upstream. + +Right now we seem to be passing index as "lowerdentry" and origin.dentry +as "upperdentry". IIUC, we should pass these parameters in reversed order +and this looks like a bug. + +Signed-off-by: Vivek Goyal +Acked-by: Amir Goldstein +Fixes: caf70cb2ba5d ("ovl: cleanup orphan index entries") +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/namei.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/overlayfs/namei.c ++++ b/fs/overlayfs/namei.c +@@ -437,7 +437,7 @@ int ovl_verify_index(struct dentry *inde + + /* Check if index is orphan and don't warn before cleaning it */ + if (d_inode(index)->i_nlink == 1 && +- ovl_get_nlink(index, origin.dentry, 0) == 0) ++ ovl_get_nlink(origin.dentry, index, 0) == 0) + err = -ENOENT; + + dput(origin.dentry); diff --git a/queue-4.14/ovl-update-ctx-pos-on-impure-dir-iteration.patch b/queue-4.14/ovl-update-ctx-pos-on-impure-dir-iteration.patch new file mode 100644 index 00000000000..7f6042557be --- /dev/null +++ b/queue-4.14/ovl-update-ctx-pos-on-impure-dir-iteration.patch @@ -0,0 +1,37 @@ +From b02a16e6413a2f782e542ef60bad9ff6bf212f8a Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Wed, 29 Nov 2017 07:35:21 +0200 +Subject: ovl: update ctx->pos on impure dir iteration + +From: Amir Goldstein + +commit b02a16e6413a2f782e542ef60bad9ff6bf212f8a upstream. + +This fixes a regression with readdir of impure dir in overlayfs +that is shared to VM via 9p fs. + +Reported-by: Miguel Bernal Marin +Fixes: 4edb83bb1041 ("ovl: constant d_ino for non-merge dirs") +Signed-off-by: Amir Goldstein +Tested-by: Miguel Bernal Marin +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/readdir.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/overlayfs/readdir.c ++++ b/fs/overlayfs/readdir.c +@@ -645,7 +645,10 @@ static int ovl_iterate_real(struct file + return PTR_ERR(rdt.cache); + } + +- return iterate_dir(od->realfile, &rdt.ctx); ++ err = iterate_dir(od->realfile, &rdt.ctx); ++ ctx->pos = rdt.ctx.pos; ++ ++ return err; + } + + diff --git a/queue-4.14/posix-timer-properly-check-sigevent-sigev_notify.patch b/queue-4.14/posix-timer-properly-check-sigevent-sigev_notify.patch new file mode 100644 index 00000000000..14ba5452119 --- /dev/null +++ b/queue-4.14/posix-timer-properly-check-sigevent-sigev_notify.patch @@ -0,0 +1,91 @@ +From cef31d9af908243421258f1df35a4a644604efbe Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Fri, 15 Dec 2017 10:32:03 +0100 +Subject: posix-timer: Properly check sigevent->sigev_notify + +From: Thomas Gleixner + +commit cef31d9af908243421258f1df35a4a644604efbe upstream. + +timer_create() specifies via sigevent->sigev_notify the signal delivery for +the new timer. The valid modes are SIGEV_NONE, SIGEV_SIGNAL, SIGEV_THREAD +and (SIGEV_SIGNAL | SIGEV_THREAD_ID). + +The sanity check in good_sigevent() is only checking the valid combination +for the SIGEV_THREAD_ID bit, i.e. SIGEV_SIGNAL, but if SIGEV_THREAD_ID is +not set it accepts any random value. + +This has no real effects on the posix timer and signal delivery code, but +it affects show_timer() which handles the output of /proc/$PID/timers. That +function uses a string array to pretty print sigev_notify. The access to +that array has no bound checks, so random sigev_notify cause access beyond +the array bounds. + +Add proper checks for the valid notify modes and remove the SIGEV_THREAD_ID +masking from various code pathes as SIGEV_NONE can never be set in +combination with SIGEV_THREAD_ID. + +Reported-by: Eric Biggers +Reported-by: Dmitry Vyukov +Reported-by: Alexey Dobriyan +Signed-off-by: Thomas Gleixner +Cc: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/posix-timers.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +--- a/kernel/time/posix-timers.c ++++ b/kernel/time/posix-timers.c +@@ -434,17 +434,22 @@ static struct pid *good_sigevent(sigeven + { + struct task_struct *rtn = current->group_leader; + +- if ((event->sigev_notify & SIGEV_THREAD_ID ) && +- (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) || +- !same_thread_group(rtn, current) || +- (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) ++ switch (event->sigev_notify) { ++ case SIGEV_SIGNAL | SIGEV_THREAD_ID: ++ rtn = find_task_by_vpid(event->sigev_notify_thread_id); ++ if (!rtn || !same_thread_group(rtn, current)) ++ return NULL; ++ /* FALLTHRU */ ++ case SIGEV_SIGNAL: ++ case SIGEV_THREAD: ++ if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) ++ return NULL; ++ /* FALLTHRU */ ++ case SIGEV_NONE: ++ return task_pid(rtn); ++ default: + return NULL; +- +- if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) && +- ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX))) +- return NULL; +- +- return task_pid(rtn); ++ } + } + + static struct k_itimer * alloc_posix_timer(void) +@@ -669,7 +674,7 @@ void common_timer_get(struct k_itimer *t + struct timespec64 ts64; + bool sig_none; + +- sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE; ++ sig_none = timr->it_sigev_notify == SIGEV_NONE; + iv = timr->it_interval; + + /* interval timer ? */ +@@ -856,7 +861,7 @@ int common_timer_set(struct k_itimer *ti + + timr->it_interval = timespec64_to_ktime(new_setting->it_interval); + expires = timespec64_to_ktime(new_setting->it_value); +- sigev_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE; ++ sigev_none = timr->it_sigev_notify == SIGEV_NONE; + + kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); + timr->it_active = !sigev_none; diff --git a/queue-4.14/revert-exec-avoid-rlimit_stack-races-with-prlimit.patch b/queue-4.14/revert-exec-avoid-rlimit_stack-races-with-prlimit.patch new file mode 100644 index 00000000000..2e2f08049c2 --- /dev/null +++ b/queue-4.14/revert-exec-avoid-rlimit_stack-races-with-prlimit.patch @@ -0,0 +1,48 @@ +From 779f4e1c6c7c661db40dfebd6dd6bda7b5f88aa3 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Tue, 12 Dec 2017 11:28:38 -0800 +Subject: Revert "exec: avoid RLIMIT_STACK races with prlimit()" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kees Cook + +commit 779f4e1c6c7c661db40dfebd6dd6bda7b5f88aa3 upstream. + +This reverts commit 04e35f4495dd560db30c25efca4eecae8ec8c375. + +SELinux runs with secureexec for all non-"noatsecure" domain transitions, +which means lots of processes end up hitting the stack hard-limit change +that was introduced in order to fix a race with prlimit(). That race fix +will need to be redesigned. + +Reported-by: Laura Abbott +Reported-by: Tomáš Trnka +Signed-off-by: Kees Cook +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exec.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1340,15 +1340,10 @@ void setup_new_exec(struct linux_binprm + * avoid bad behavior from the prior rlimits. This has to + * happen before arch_pick_mmap_layout(), which examines + * RLIMIT_STACK, but after the point of no return to avoid +- * races from other threads changing the limits. This also +- * must be protected from races with prlimit() calls. ++ * needing to clean up the change on failure. + */ +- task_lock(current->group_leader); + if (current->signal->rlim[RLIMIT_STACK].rlim_cur > _STK_LIM) + current->signal->rlim[RLIMIT_STACK].rlim_cur = _STK_LIM; +- if (current->signal->rlim[RLIMIT_STACK].rlim_max > _STK_LIM) +- current->signal->rlim[RLIMIT_STACK].rlim_max = _STK_LIM; +- task_unlock(current->group_leader); + } + + arch_pick_mmap_layout(current->mm); diff --git a/queue-4.14/sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch b/queue-4.14/sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch new file mode 100644 index 00000000000..2668ebd1b34 --- /dev/null +++ b/queue-4.14/sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch @@ -0,0 +1,82 @@ +From f73c52a5bcd1710994e53fbccc378c42b97a06b6 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Sat, 2 Dec 2017 13:04:54 -0500 +Subject: sched/rt: Do not pull from current CPU if only one CPU to pull + +From: Steven Rostedt + +commit f73c52a5bcd1710994e53fbccc378c42b97a06b6 upstream. + +Daniel Wagner reported a crash on the BeagleBone Black SoC. + +This is a single CPU architecture, and does not have a functional +arch_send_call_function_single_ipi() implementation which can crash +the kernel if that is called. + +As it only has one CPU, it shouldn't be called, but if the kernel is +compiled for SMP, the push/pull RT scheduling logic now calls it for +irq_work if the one CPU is overloaded, it can use that function to call +itself and crash the kernel. + +Ideally, we should disable the SCHED_FEAT(RT_PUSH_IPI) if the system +only has a single CPU. But SCHED_FEAT is a constant if sched debugging +is turned off. Another fix can also be used, and this should also help +with normal SMP machines. That is, do not initiate the pull code if +there's only one RT overloaded CPU, and that CPU happens to be the +current CPU that is scheduling in a lower priority task. + +Even on a system with many CPUs, if there's many RT tasks waiting to +run on a single CPU, and that CPU schedules in another RT task of lower +priority, it will initiate the PULL logic in case there's a higher +priority RT task on another CPU that is waiting to run. But if there is +no other CPU with waiting RT tasks, it will initiate the RT pull logic +on itself (as it still has RT tasks waiting to run). This is a wasted +effort. + +Not only does this help with SMP code where the current CPU is the only +one with RT overloaded tasks, it should also solve the issue that +Daniel encountered, because it will prevent the PULL logic from +executing, as there's only one CPU on the system, and the check added +here will cause it to exit the RT pull code. + +Reported-by: Daniel Wagner +Signed-off-by: Steven Rostedt (VMware) +Acked-by: Peter Zijlstra +Cc: Linus Torvalds +Cc: Sebastian Andrzej Siewior +Cc: Thomas Gleixner +Cc: linux-rt-users +Fixes: 4bdced5c9 ("sched/rt: Simplify the IPI based RT balancing logic") +Link: http://lkml.kernel.org/r/20171202130454.4cbbfe8d@vmware.local.home +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched/rt.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/kernel/sched/rt.c ++++ b/kernel/sched/rt.c +@@ -2034,8 +2034,9 @@ static void pull_rt_task(struct rq *this + bool resched = false; + struct task_struct *p; + struct rq *src_rq; ++ int rt_overload_count = rt_overloaded(this_rq); + +- if (likely(!rt_overloaded(this_rq))) ++ if (likely(!rt_overload_count)) + return; + + /* +@@ -2044,6 +2045,11 @@ static void pull_rt_task(struct rq *this + */ + smp_rmb(); + ++ /* If we are the only overloaded CPU do nothing */ ++ if (rt_overload_count == 1 && ++ cpumask_test_cpu(this_rq->cpu, this_rq->rd->rto_mask)) ++ return; ++ + #ifdef HAVE_RT_PUSH_IPI + if (sched_feat(RT_PUSH_IPI)) { + tell_cpu_to_push(this_rq); diff --git a/queue-4.14/scsi-core-fix-a-scsi_show_rq-null-pointer-dereference.patch b/queue-4.14/scsi-core-fix-a-scsi_show_rq-null-pointer-dereference.patch new file mode 100644 index 00000000000..49acbcde062 --- /dev/null +++ b/queue-4.14/scsi-core-fix-a-scsi_show_rq-null-pointer-dereference.patch @@ -0,0 +1,89 @@ +From 14e3062fb18532175af4d1c4073597999f7a2248 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Tue, 5 Dec 2017 16:57:51 -0800 +Subject: scsi: core: Fix a scsi_show_rq() NULL pointer dereference + +From: Bart Van Assche + +commit 14e3062fb18532175af4d1c4073597999f7a2248 upstream. + +Avoid that scsi_show_rq() triggers a NULL pointer dereference if called +after sd_uninit_command(). Swap the NULL pointer assignment and the +mempool_free() call in sd_uninit_command() to make it less likely that +scsi_show_rq() triggers a use-after-free. Note: even with these changes +scsi_show_rq() can trigger a use-after-free but that's a lesser evil +than e.g. suppressing debug information for T10 PI Type 2 commands +completely. This patch fixes the following oops: + +BUG: unable to handle kernel NULL pointer dereference at (null) +IP: scsi_format_opcode_name+0x1a/0x1c0 +CPU: 1 PID: 1881 Comm: cat Not tainted 4.14.0-rc2.blk_mq_io_hang+ #516 +Call Trace: + __scsi_format_command+0x27/0xc0 + scsi_show_rq+0x5c/0xc0 + __blk_mq_debugfs_rq_show+0x116/0x130 + blk_mq_debugfs_rq_show+0xe/0x10 + seq_read+0xfe/0x3b0 + full_proxy_read+0x54/0x90 + __vfs_read+0x37/0x160 + vfs_read+0x96/0x130 + SyS_read+0x55/0xc0 + entry_SYSCALL_64_fastpath+0x1a/0xa5 + +[mkp: added Type 2] + +Fixes: 0eebd005dd07 ("scsi: Implement blk_mq_ops.show_rq()") +Reported-by: Ming Lei +Signed-off-by: Bart Van Assche +Cc: James E.J. Bottomley +Cc: Martin K. Petersen +Cc: Ming Lei +Cc: Christoph Hellwig +Cc: Hannes Reinecke +Cc: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_debugfs.c | 6 ++++-- + drivers/scsi/sd.c | 4 +++- + 2 files changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/scsi_debugfs.c ++++ b/drivers/scsi/scsi_debugfs.c +@@ -8,9 +8,11 @@ void scsi_show_rq(struct seq_file *m, st + { + struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req); + int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc); +- char buf[80]; ++ const u8 *const cdb = READ_ONCE(cmd->cmnd); ++ char buf[80] = "(?)"; + +- __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len); ++ if (cdb) ++ __scsi_format_command(buf, sizeof(buf), cdb, cmd->cmd_len); + seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf, + cmd->retries, msecs / 1000, msecs % 1000); + } +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -1284,6 +1284,7 @@ static int sd_init_command(struct scsi_c + static void sd_uninit_command(struct scsi_cmnd *SCpnt) + { + struct request *rq = SCpnt->request; ++ u8 *cmnd; + + if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK) + sd_zbc_write_unlock_zone(SCpnt); +@@ -1292,9 +1293,10 @@ static void sd_uninit_command(struct scs + __free_page(rq->special_vec.bv_page); + + if (SCpnt->cmnd != scsi_req(rq)->cmd) { +- mempool_free(SCpnt->cmnd, sd_cdb_pool); ++ cmnd = SCpnt->cmnd; + SCpnt->cmnd = NULL; + SCpnt->cmd_len = 0; ++ mempool_free(cmnd, sd_cdb_pool); + } + } + diff --git a/queue-4.14/scsi-libsas-fix-length-error-in-sas_smp_handler.patch b/queue-4.14/scsi-libsas-fix-length-error-in-sas_smp_handler.patch new file mode 100644 index 00000000000..c1b11b66a4c --- /dev/null +++ b/queue-4.14/scsi-libsas-fix-length-error-in-sas_smp_handler.patch @@ -0,0 +1,66 @@ +From 621f6401fdeefe96dfe9eab4b167c7c39f552bb0 Mon Sep 17 00:00:00 2001 +From: Jason Yan +Date: Mon, 11 Dec 2017 15:03:33 +0800 +Subject: scsi: libsas: fix length error in sas_smp_handler() + +From: Jason Yan + +commit 621f6401fdeefe96dfe9eab4b167c7c39f552bb0 upstream. + +The return value of smp_execute_task_sg() is the untransferred residual, +but bsg_job_done() requires the length of payload received. This makes +SMP passthrough commands from userland by sg ioctl to libsas get a wrong +response. The userland tools such as smp_utils failed because of these +wrong responses: + +~#smp_discover /dev/bsg/expander-2\:13 +response too short, len=0 +~#smp_discover /dev/bsg/expander-2\:134 +response too short, len=0 + +Fix this by passing the actual received length to bsg_job_done(). And if +smp_execute_task_sg() returns 0, this means received length is exactly +the buffer length. + +[mkp: typo] + +Fixes: 651a01364994 ("scsi: scsi_transport_sas: switch to bsg-lib for SMP passthrough") +Signed-off-by: Jason Yan +Reported-by: chenqilin +Tested-by: chenqilin +CC: Christoph Hellwig +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/libsas/sas_expander.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/scsi/libsas/sas_expander.c ++++ b/drivers/scsi/libsas/sas_expander.c +@@ -2145,7 +2145,7 @@ void sas_smp_handler(struct bsg_job *job + struct sas_rphy *rphy) + { + struct domain_device *dev; +- unsigned int reslen = 0; ++ unsigned int rcvlen = 0; + int ret = -EINVAL; + + /* no rphy means no smp target support (ie aic94xx host) */ +@@ -2179,12 +2179,12 @@ void sas_smp_handler(struct bsg_job *job + + ret = smp_execute_task_sg(dev, job->request_payload.sg_list, + job->reply_payload.sg_list); +- if (ret > 0) { +- /* positive number is the untransferred residual */ +- reslen = ret; ++ if (ret >= 0) { ++ /* bsg_job_done() requires the length received */ ++ rcvlen = job->reply_payload.payload_len - ret; + ret = 0; + } + + out: +- bsg_job_done(job, ret, reslen); ++ bsg_job_done(job, ret, rcvlen); + } diff --git a/queue-4.14/series b/queue-4.14/series index 0d43823764a..aa174f5c3c9 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -6,3 +6,41 @@ crypto-salsa20-fix-blkcipher_walk-api-usage.patch crypto-af_alg-fix-null-pointer-dereference-in.patch cifs-fix-null-deref-in-smb2_read.patch string.h-workaround-for-increased-stack-usage.patch +autofs-fix-careless-error-in-recent-commit.patch +kernel-make-groups_sort-calling-a-responsibility-group_info-allocators.patch +mm-oom_reaper-fix-memory-corruption.patch +tracing-allocate-mask_str-buffer-dynamically.patch +usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch +usb-core-prevent-malicious-bnuminterfaces-overflow.patch +ovl-pass-ovl_get_nlink-parameters-in-right-order.patch +ovl-update-ctx-pos-on-impure-dir-iteration.patch +usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch +usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch +usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch +usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch +mmc-core-apply-no_cmd23-quirk-to-some-specific-cards.patch +ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch +usb-xhci-fix-tds-for-mtk-xhci1.1.patch +xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch +ib-core-bound-check-alternate-path-port-number.patch +ib-core-don-t-enforce-pkey-security-on-smi-mads.patch +nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch +arm64-mm-fix-pte_mkclean-pte_mkdirty-semantics.patch +arm64-initialise-high_memory-global-variable-earlier.patch +arm64-fix-config_debug_wx-address-reporting.patch +scsi-core-fix-a-scsi_show_rq-null-pointer-dereference.patch +scsi-libsas-fix-length-error-in-sas_smp_handler.patch +sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch +dm-fix-various-targets-to-dm_register_target-after-module-__init-resources-created.patch +sunrpc-fix-a-race-in-the-receive-code-path.patch +iw_cxgb4-only-insert-drain-cqes-if-wq-is-flushed.patch +x86-boot-compressed-64-detect-and-handle-5-level-paging-at-boot-time.patch +x86-boot-compressed-64-print-error-if-5-level-paging-is-not-supported.patch +eeprom-at24-change-nvmem-stride-to-1.patch +posix-timer-properly-check-sigevent-sigev_notify.patch +dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch +revert-exec-avoid-rlimit_stack-races-with-prlimit.patch +ext4-support-fast-symlinks-from-ext3-file-systems.patch +ext4-fix-fdatasync-2-after-fallocate-2-operation.patch +ext4-add-missing-error-check-in-__ext4_new_inode.patch +ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch diff --git a/queue-4.14/sunrpc-fix-a-race-in-the-receive-code-path.patch b/queue-4.14/sunrpc-fix-a-race-in-the-receive-code-path.patch new file mode 100644 index 00000000000..09e9c0d0682 --- /dev/null +++ b/queue-4.14/sunrpc-fix-a-race-in-the-receive-code-path.patch @@ -0,0 +1,80 @@ +From 90d91b0cd371193d9dbfa9beacab8ab9a4cb75e0 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Thu, 14 Dec 2017 21:24:08 -0500 +Subject: SUNRPC: Fix a race in the receive code path + +From: Trond Myklebust + +commit 90d91b0cd371193d9dbfa9beacab8ab9a4cb75e0 upstream. + +We must ensure that the call to rpc_sleep_on() in xprt_transmit() cannot +race with the call to xprt_complete_rqst(). + +Reported-by: Chuck Lever +Link: https://bugzilla.linux-nfs.org/show_bug.cgi?id=317 +Fixes: ce7c252a8c74 ("SUNRPC: Add a separate spinlock to protect..") +Reviewed-by: Chuck Lever +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/xprt.c | 28 +++++++++++++++++++--------- + 1 file changed, 19 insertions(+), 9 deletions(-) + +--- a/net/sunrpc/xprt.c ++++ b/net/sunrpc/xprt.c +@@ -1001,6 +1001,7 @@ void xprt_transmit(struct rpc_task *task + { + struct rpc_rqst *req = task->tk_rqstp; + struct rpc_xprt *xprt = req->rq_xprt; ++ unsigned int connect_cookie; + int status, numreqs; + + dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); +@@ -1024,6 +1025,7 @@ void xprt_transmit(struct rpc_task *task + } else if (!req->rq_bytes_sent) + return; + ++ connect_cookie = xprt->connect_cookie; + req->rq_xtime = ktime_get(); + status = xprt->ops->send_request(task); + trace_xprt_transmit(xprt, req->rq_xid, status); +@@ -1047,20 +1049,28 @@ void xprt_transmit(struct rpc_task *task + xprt->stat.bklog_u += xprt->backlog.qlen; + xprt->stat.sending_u += xprt->sending.qlen; + xprt->stat.pending_u += xprt->pending.qlen; ++ spin_unlock_bh(&xprt->transport_lock); + +- /* Don't race with disconnect */ +- if (!xprt_connected(xprt)) +- task->tk_status = -ENOTCONN; +- else { ++ req->rq_connect_cookie = connect_cookie; ++ if (rpc_reply_expected(task) && !READ_ONCE(req->rq_reply_bytes_recvd)) { + /* +- * Sleep on the pending queue since +- * we're expecting a reply. ++ * Sleep on the pending queue if we're expecting a reply. ++ * The spinlock ensures atomicity between the test of ++ * req->rq_reply_bytes_recvd, and the call to rpc_sleep_on(). + */ +- if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task)) ++ spin_lock(&xprt->recv_lock); ++ if (!req->rq_reply_bytes_recvd) { + rpc_sleep_on(&xprt->pending, task, xprt_timer); +- req->rq_connect_cookie = xprt->connect_cookie; ++ /* ++ * Send an extra queue wakeup call if the ++ * connection was dropped in case the call to ++ * rpc_sleep_on() raced. ++ */ ++ if (!xprt_connected(xprt)) ++ xprt_wake_pending_tasks(xprt, -ENOTCONN); ++ } ++ spin_unlock(&xprt->recv_lock); + } +- spin_unlock_bh(&xprt->transport_lock); + } + + static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task) diff --git a/queue-4.14/tracing-allocate-mask_str-buffer-dynamically.patch b/queue-4.14/tracing-allocate-mask_str-buffer-dynamically.patch new file mode 100644 index 00000000000..b13a3c918a8 --- /dev/null +++ b/queue-4.14/tracing-allocate-mask_str-buffer-dynamically.patch @@ -0,0 +1,97 @@ +From 90e406f96f630c07d631a021fd4af10aac913e77 Mon Sep 17 00:00:00 2001 +From: Changbin Du +Date: Thu, 30 Nov 2017 11:39:43 +0800 +Subject: tracing: Allocate mask_str buffer dynamically + +From: Changbin Du + +commit 90e406f96f630c07d631a021fd4af10aac913e77 upstream. + +The default NR_CPUS can be very large, but actual possible nr_cpu_ids +usually is very small. For my x86 distribution, the NR_CPUS is 8192 and +nr_cpu_ids is 4. About 2 pages are wasted. + +Most machines don't have so many CPUs, so define a array with NR_CPUS +just wastes memory. So let's allocate the buffer dynamically when need. + +With this change, the mutext tracing_cpumask_update_lock also can be +removed now, which was used to protect mask_str. + +Link: http://lkml.kernel.org/r/1512013183-19107-1-git-send-email-changbin.du@intel.com + +Fixes: 36dfe9252bd4c ("ftrace: make use of tracing_cpumask") +Signed-off-by: Changbin Du +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace.c | 29 +++++++++-------------------- + 1 file changed, 9 insertions(+), 20 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -4178,37 +4178,30 @@ static const struct file_operations show + .llseek = seq_lseek, + }; + +-/* +- * The tracer itself will not take this lock, but still we want +- * to provide a consistent cpumask to user-space: +- */ +-static DEFINE_MUTEX(tracing_cpumask_update_lock); +- +-/* +- * Temporary storage for the character representation of the +- * CPU bitmask (and one more byte for the newline): +- */ +-static char mask_str[NR_CPUS + 1]; +- + static ssize_t + tracing_cpumask_read(struct file *filp, char __user *ubuf, + size_t count, loff_t *ppos) + { + struct trace_array *tr = file_inode(filp)->i_private; ++ char *mask_str; + int len; + +- mutex_lock(&tracing_cpumask_update_lock); ++ len = snprintf(NULL, 0, "%*pb\n", ++ cpumask_pr_args(tr->tracing_cpumask)) + 1; ++ mask_str = kmalloc(len, GFP_KERNEL); ++ if (!mask_str) ++ return -ENOMEM; + +- len = snprintf(mask_str, count, "%*pb\n", ++ len = snprintf(mask_str, len, "%*pb\n", + cpumask_pr_args(tr->tracing_cpumask)); + if (len >= count) { + count = -EINVAL; + goto out_err; + } +- count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1); ++ count = simple_read_from_buffer(ubuf, count, ppos, mask_str, len); + + out_err: +- mutex_unlock(&tracing_cpumask_update_lock); ++ kfree(mask_str); + + return count; + } +@@ -4228,8 +4221,6 @@ tracing_cpumask_write(struct file *filp, + if (err) + goto err_unlock; + +- mutex_lock(&tracing_cpumask_update_lock); +- + local_irq_disable(); + arch_spin_lock(&tr->max_lock); + for_each_tracing_cpu(cpu) { +@@ -4252,8 +4243,6 @@ tracing_cpumask_write(struct file *filp, + local_irq_enable(); + + cpumask_copy(tr->tracing_cpumask, tracing_cpumask_new); +- +- mutex_unlock(&tracing_cpumask_update_lock); + free_cpumask_var(tracing_cpumask_new); + + return count; diff --git a/queue-4.14/usb-core-prevent-malicious-bnuminterfaces-overflow.patch b/queue-4.14/usb-core-prevent-malicious-bnuminterfaces-overflow.patch new file mode 100644 index 00000000000..dadf0d7501b --- /dev/null +++ b/queue-4.14/usb-core-prevent-malicious-bnuminterfaces-overflow.patch @@ -0,0 +1,47 @@ +From 48a4ff1c7bb5a32d2e396b03132d20d552c0eca7 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 12 Dec 2017 14:25:13 -0500 +Subject: USB: core: prevent malicious bNumInterfaces overflow + +From: Alan Stern + +commit 48a4ff1c7bb5a32d2e396b03132d20d552c0eca7 upstream. + +A malicious USB device with crafted descriptors can cause the kernel +to access unallocated memory by setting the bNumInterfaces value too +high in a configuration descriptor. Although the value is adjusted +during parsing, this adjustment is skipped in one of the error return +paths. + +This patch prevents the problem by setting bNumInterfaces to 0 +initially. The existing code already sets it to the proper value +after parsing is complete. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -555,6 +555,9 @@ static int usb_parse_configuration(struc + unsigned iad_num = 0; + + memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); ++ nintf = nintf_orig = config->desc.bNumInterfaces; ++ config->desc.bNumInterfaces = 0; // Adjusted later ++ + if (config->desc.bDescriptorType != USB_DT_CONFIG || + config->desc.bLength < USB_DT_CONFIG_SIZE || + config->desc.bLength > size) { +@@ -568,7 +571,6 @@ static int usb_parse_configuration(struc + buffer += config->desc.bLength; + size -= config->desc.bLength; + +- nintf = nintf_orig = config->desc.bNumInterfaces; + if (nintf > USB_MAXINTERFACES) { + dev_warn(ddev, "config %d has too many interfaces: %d, " + "using maximum allowed: %d\n", diff --git a/queue-4.14/usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch b/queue-4.14/usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch new file mode 100644 index 00000000000..2a07024fdb7 --- /dev/null +++ b/queue-4.14/usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch @@ -0,0 +1,65 @@ +From 62354454625741f0569c2cbe45b2d192f8fd258e Mon Sep 17 00:00:00 2001 +From: David Kozub +Date: Tue, 5 Dec 2017 22:40:04 +0100 +Subject: USB: uas and storage: Add US_FL_BROKEN_FUA for another JMicron JMS567 ID + +From: David Kozub + +commit 62354454625741f0569c2cbe45b2d192f8fd258e upstream. + +There is another JMS567-based USB3 UAS enclosure (152d:0578) that fails +with the following error: + +[sda] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE +[sda] tag#0 Sense Key : Illegal Request [current] +[sda] tag#0 Add. Sense: Invalid field in cdb + +The issue occurs both with UAS (occasionally) and mass storage +(immediately after mounting a FS on a disk in the enclosure). + +Enabling US_FL_BROKEN_FUA quirk solves this issue. + +This patch adds an UNUSUAL_DEV with US_FL_BROKEN_FUA for the enclosure +for both UAS and mass storage. + +Signed-off-by: David Kozub +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/unusual_devs.h | 7 +++++++ + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 2 files changed, 14 insertions(+) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -2113,6 +2113,13 @@ UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA ), + ++/* Reported by David Kozub */ ++UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, ++ "JMicron", ++ "JMS567", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_BROKEN_FUA), ++ + /* + * Reported by Alexandre Oliva + * JMicron responds to USN and several other SCSI ioctls with a +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -142,6 +142,13 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x99 + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES), + ++/* Reported-by: David Kozub */ ++UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, ++ "JMicron", ++ "JMS567", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_BROKEN_FUA), ++ + /* Reported-by: Hans de Goede */ + UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, + "VIA", diff --git a/queue-4.14/usb-xhci-fix-tds-for-mtk-xhci1.1.patch b/queue-4.14/usb-xhci-fix-tds-for-mtk-xhci1.1.patch new file mode 100644 index 00000000000..97fada558c6 --- /dev/null +++ b/queue-4.14/usb-xhci-fix-tds-for-mtk-xhci1.1.patch @@ -0,0 +1,47 @@ +From 72b663a99c074a8d073e7ecdae446cfb024ef551 Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun +Date: Fri, 8 Dec 2017 18:10:06 +0200 +Subject: usb: xhci: fix TDS for MTK xHCI1.1 + +From: Chunfeng Yun + +commit 72b663a99c074a8d073e7ecdae446cfb024ef551 upstream. + +For MTK's xHCI 1.0 or latter, TD size is the number of max +packet sized packets remaining in the TD, not including +this TRB (following spec). + +For MTK's xHCI 0.96 and older, TD size is the number of max +packet sized packets remaining in the TD, including this TRB +(not following spec). + +Signed-off-by: Chunfeng Yun +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -3121,7 +3121,7 @@ static u32 xhci_td_remainder(struct xhci + { + u32 maxp, total_packet_count; + +- /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */ ++ /* MTK xHCI 0.96 contains some features from 1.0 */ + if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST)) + return ((td_total_len - transferred) >> 10); + +@@ -3130,8 +3130,8 @@ static u32 xhci_td_remainder(struct xhci + trb_buff_len == td_total_len) + return 0; + +- /* for MTK xHCI, TD size doesn't include this TRB */ +- if (xhci->quirks & XHCI_MTK_HOST) ++ /* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */ ++ if ((xhci->quirks & XHCI_MTK_HOST) && (xhci->hci_version < 0x100)) + trb_buff_len = 0; + + maxp = usb_endpoint_maxp(&urb->ep->desc); diff --git a/queue-4.14/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch b/queue-4.14/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch new file mode 100644 index 00000000000..ae59a2f81ff --- /dev/null +++ b/queue-4.14/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch @@ -0,0 +1,71 @@ +From 635f545a7e8be7596b9b2b6a43cab6bbd5a88e43 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 7 Dec 2017 14:16:47 -0700 +Subject: usbip: fix stub_rx: get_pipe() to validate endpoint number + +From: Shuah Khan + +commit 635f545a7e8be7596b9b2b6a43cab6bbd5a88e43 upstream. + +get_pipe() routine doesn't validate the input endpoint number +and uses to reference ep_in and ep_out arrays. Invalid endpoint +number can trigger BUG(). Range check the epnum and returning +error instead of calling BUG(). + +Change caller stub_recv_cmd_submit() to handle the get_pipe() +error return. + +Reported-by: Secunia Research +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/stub_rx.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/usb/usbip/stub_rx.c ++++ b/drivers/usb/usbip/stub_rx.c +@@ -342,15 +342,15 @@ static int get_pipe(struct stub_device * + struct usb_host_endpoint *ep; + struct usb_endpoint_descriptor *epd = NULL; + ++ if (epnum < 0 || epnum > 15) ++ goto err_ret; ++ + if (dir == USBIP_DIR_IN) + ep = udev->ep_in[epnum & 0x7f]; + else + ep = udev->ep_out[epnum & 0x7f]; +- if (!ep) { +- dev_err(&sdev->udev->dev, "no such endpoint?, %d\n", +- epnum); +- BUG(); +- } ++ if (!ep) ++ goto err_ret; + + epd = &ep->desc; + if (usb_endpoint_xfer_control(epd)) { +@@ -381,9 +381,10 @@ static int get_pipe(struct stub_device * + return usb_rcvisocpipe(udev, epnum); + } + ++err_ret: + /* NOT REACHED */ +- dev_err(&sdev->udev->dev, "get pipe, epnum %d\n", epnum); +- return 0; ++ dev_err(&sdev->udev->dev, "get pipe() invalid epnum %d\n", epnum); ++ return -1; + } + + static void masking_bogus_flags(struct urb *urb) +@@ -449,6 +450,9 @@ static void stub_recv_cmd_submit(struct + struct usb_device *udev = sdev->udev; + int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); + ++ if (pipe == -1) ++ return; ++ + priv = stub_priv_alloc(sdev, pdu); + if (!priv) + return; diff --git a/queue-4.14/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch b/queue-4.14/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch new file mode 100644 index 00000000000..e0c7cb9ccbd --- /dev/null +++ b/queue-4.14/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch @@ -0,0 +1,106 @@ +From c6688ef9f29762e65bce325ef4acd6c675806366 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 7 Dec 2017 14:16:48 -0700 +Subject: usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input + +From: Shuah Khan + +commit c6688ef9f29762e65bce325ef4acd6c675806366 upstream. + +Harden CMD_SUBMIT path to handle malicious input that could trigger +large memory allocations. Add checks to validate transfer_buffer_length +and number_of_packets to protect against bad input requesting for +unbounded memory allocations. Validate early in get_pipe() and return +failure. + +Reported-by: Secunia Research +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/stub_rx.c | 35 +++++++++++++++++++++++++++++++---- + 1 file changed, 31 insertions(+), 4 deletions(-) + +--- a/drivers/usb/usbip/stub_rx.c ++++ b/drivers/usb/usbip/stub_rx.c +@@ -336,11 +336,13 @@ static struct stub_priv *stub_priv_alloc + return priv; + } + +-static int get_pipe(struct stub_device *sdev, int epnum, int dir) ++static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) + { + struct usb_device *udev = sdev->udev; + struct usb_host_endpoint *ep; + struct usb_endpoint_descriptor *epd = NULL; ++ int epnum = pdu->base.ep; ++ int dir = pdu->base.direction; + + if (epnum < 0 || epnum > 15) + goto err_ret; +@@ -353,6 +355,15 @@ static int get_pipe(struct stub_device * + goto err_ret; + + epd = &ep->desc; ++ ++ /* validate transfer_buffer_length */ ++ if (pdu->u.cmd_submit.transfer_buffer_length > INT_MAX) { ++ dev_err(&sdev->udev->dev, ++ "CMD_SUBMIT: -EMSGSIZE transfer_buffer_length %d\n", ++ pdu->u.cmd_submit.transfer_buffer_length); ++ return -1; ++ } ++ + if (usb_endpoint_xfer_control(epd)) { + if (dir == USBIP_DIR_OUT) + return usb_sndctrlpipe(udev, epnum); +@@ -375,6 +386,21 @@ static int get_pipe(struct stub_device * + } + + if (usb_endpoint_xfer_isoc(epd)) { ++ /* validate packet size and number of packets */ ++ unsigned int maxp, packets, bytes; ++ ++ maxp = usb_endpoint_maxp(epd); ++ maxp *= usb_endpoint_maxp_mult(epd); ++ bytes = pdu->u.cmd_submit.transfer_buffer_length; ++ packets = DIV_ROUND_UP(bytes, maxp); ++ ++ if (pdu->u.cmd_submit.number_of_packets < 0 || ++ pdu->u.cmd_submit.number_of_packets > packets) { ++ dev_err(&sdev->udev->dev, ++ "CMD_SUBMIT: isoc invalid num packets %d\n", ++ pdu->u.cmd_submit.number_of_packets); ++ return -1; ++ } + if (dir == USBIP_DIR_OUT) + return usb_sndisocpipe(udev, epnum); + else +@@ -383,7 +409,7 @@ static int get_pipe(struct stub_device * + + err_ret: + /* NOT REACHED */ +- dev_err(&sdev->udev->dev, "get pipe() invalid epnum %d\n", epnum); ++ dev_err(&sdev->udev->dev, "CMD_SUBMIT: invalid epnum %d\n", epnum); + return -1; + } + +@@ -448,7 +474,7 @@ static void stub_recv_cmd_submit(struct + struct stub_priv *priv; + struct usbip_device *ud = &sdev->ud; + struct usb_device *udev = sdev->udev; +- int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); ++ int pipe = get_pipe(sdev, pdu); + + if (pipe == -1) + return; +@@ -470,7 +496,8 @@ static void stub_recv_cmd_submit(struct + } + + /* allocate urb transfer buffer, if needed */ +- if (pdu->u.cmd_submit.transfer_buffer_length > 0) { ++ if (pdu->u.cmd_submit.transfer_buffer_length > 0 && ++ pdu->u.cmd_submit.transfer_buffer_length <= INT_MAX) { + priv->urb->transfer_buffer = + kzalloc(pdu->u.cmd_submit.transfer_buffer_length, + GFP_KERNEL); diff --git a/queue-4.14/usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch b/queue-4.14/usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch new file mode 100644 index 00000000000..9a2c705722f --- /dev/null +++ b/queue-4.14/usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch @@ -0,0 +1,38 @@ +From be6123df1ea8f01ee2f896a16c2b7be3e4557a5a Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 7 Dec 2017 14:16:50 -0700 +Subject: usbip: fix stub_send_ret_submit() vulnerability to null transfer_buffer + +From: Shuah Khan + +commit be6123df1ea8f01ee2f896a16c2b7be3e4557a5a upstream. + +stub_send_ret_submit() handles urb with a potential null transfer_buffer, +when it replays a packet with potential malicious data that could contain +a null buffer. Add a check for the condition when actual_length > 0 and +transfer_buffer is null. + +Reported-by: Secunia Research +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/stub_tx.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/usbip/stub_tx.c ++++ b/drivers/usb/usbip/stub_tx.c +@@ -181,6 +181,13 @@ static int stub_send_ret_submit(struct s + memset(&pdu_header, 0, sizeof(pdu_header)); + memset(&msg, 0, sizeof(msg)); + ++ if (urb->actual_length > 0 && !urb->transfer_buffer) { ++ dev_err(&sdev->udev->dev, ++ "urb: actual_length %d transfer_buffer null\n", ++ urb->actual_length); ++ return -1; ++ } ++ + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + iovnum = 2 + urb->number_of_packets; + else diff --git a/queue-4.14/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch b/queue-4.14/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch new file mode 100644 index 00000000000..f15b8772ef6 --- /dev/null +++ b/queue-4.14/usbip-prevent-vhci_hcd-driver-from-leaking-a-socket-pointer-address.patch @@ -0,0 +1,129 @@ +From 2f2d0088eb93db5c649d2a5e34a3800a8a935fc5 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 7 Dec 2017 14:16:49 -0700 +Subject: usbip: prevent vhci_hcd driver from leaking a socket pointer address + +From: Shuah Khan + +commit 2f2d0088eb93db5c649d2a5e34a3800a8a935fc5 upstream. + +When a client has a USB device attached over IP, the vhci_hcd driver is +locally leaking a socket pointer address via the + +/sys/devices/platform/vhci_hcd/status file (world-readable) and in debug +output when "usbip --debug port" is run. + +Fix it to not leak. The socket pointer address is not used at the moment +and it was made visible as a convenient way to find IP address from socket +pointer address by looking up /proc/net/{tcp,tcp6}. + +As this opens a security hole, the fix replaces socket pointer address with +sockfd. + +Reported-by: Secunia Research +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/usbip_common.h | 1 + + drivers/usb/usbip/vhci_sysfs.c | 25 ++++++++++++++++--------- + tools/usb/usbip/libsrc/vhci_driver.c | 8 ++++---- + 3 files changed, 21 insertions(+), 13 deletions(-) + +--- a/drivers/usb/usbip/usbip_common.h ++++ b/drivers/usb/usbip/usbip_common.h +@@ -270,6 +270,7 @@ struct usbip_device { + /* lock for status */ + spinlock_t lock; + ++ int sockfd; + struct socket *tcp_socket; + + struct task_struct *tcp_rx; +--- a/drivers/usb/usbip/vhci_sysfs.c ++++ b/drivers/usb/usbip/vhci_sysfs.c +@@ -31,15 +31,20 @@ + + /* + * output example: +- * hub port sta spd dev socket local_busid +- * hs 0000 004 000 00000000 c5a7bb80 1-2.3 ++ * hub port sta spd dev sockfd local_busid ++ * hs 0000 004 000 00000000 3 1-2.3 + * ................................................ +- * ss 0008 004 000 00000000 d8cee980 2-3.4 ++ * ss 0008 004 000 00000000 4 2-3.4 + * ................................................ + * +- * IP address can be retrieved from a socket pointer address by looking +- * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a +- * port number and its peer IP address. ++ * Output includes socket fd instead of socket pointer address to avoid ++ * leaking kernel memory address in: ++ * /sys/devices/platform/vhci_hcd.0/status and in debug output. ++ * The socket pointer address is not used at the moment and it was made ++ * visible as a convenient way to find IP address from socket pointer ++ * address by looking up /proc/net/{tcp,tcp6}. As this opens a security ++ * hole, the change is made to use sockfd instead. ++ * + */ + static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev) + { +@@ -53,8 +58,8 @@ static void port_show_vhci(char **out, i + if (vdev->ud.status == VDEV_ST_USED) { + *out += sprintf(*out, "%03u %08x ", + vdev->speed, vdev->devid); +- *out += sprintf(*out, "%16p %s", +- vdev->ud.tcp_socket, ++ *out += sprintf(*out, "%u %s", ++ vdev->ud.sockfd, + dev_name(&vdev->udev->dev)); + + } else { +@@ -174,7 +179,8 @@ static ssize_t nports_show(struct device + char *s = out; + + /* +- * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2. ++ * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, ++ * thus the * 2. + */ + out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); + return out - s; +@@ -380,6 +386,7 @@ static ssize_t store_attach(struct devic + + vdev->devid = devid; + vdev->speed = speed; ++ vdev->ud.sockfd = sockfd; + vdev->ud.tcp_socket = socket; + vdev->ud.status = VDEV_ST_NOTASSIGNED; + +--- a/tools/usb/usbip/libsrc/vhci_driver.c ++++ b/tools/usb/usbip/libsrc/vhci_driver.c +@@ -50,14 +50,14 @@ static int parse_status(const char *valu + + while (*c != '\0') { + int port, status, speed, devid; +- unsigned long socket; ++ int sockfd; + char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; + char hub[3]; + +- ret = sscanf(c, "%2s %d %d %d %x %lx %31s\n", ++ ret = sscanf(c, "%2s %d %d %d %x %u %31s\n", + hub, &port, &status, &speed, +- &devid, &socket, lbusid); ++ &devid, &sockfd, lbusid); + + if (ret < 5) { + dbg("sscanf failed: %d", ret); +@@ -66,7 +66,7 @@ static int parse_status(const char *valu + + dbg("hub %s port %d status %d speed %d devid %x", + hub, port, status, speed, devid); +- dbg("socket %lx lbusid %s", socket, lbusid); ++ dbg("sockfd %u lbusid %s", sockfd, lbusid); + + /* if a device is connected, look at it */ + idev = &vhci_driver->idev[port]; diff --git a/queue-4.14/x86-boot-compressed-64-detect-and-handle-5-level-paging-at-boot-time.patch b/queue-4.14/x86-boot-compressed-64-detect-and-handle-5-level-paging-at-boot-time.patch new file mode 100644 index 00000000000..4a63ea5a219 --- /dev/null +++ b/queue-4.14/x86-boot-compressed-64-detect-and-handle-5-level-paging-at-boot-time.patch @@ -0,0 +1,101 @@ +From 08529078d8d9adf689bf39cc38d53979a0869970 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Mon, 4 Dec 2017 15:40:55 +0300 +Subject: x86/boot/compressed/64: Detect and handle 5-level paging at boot-time + +From: Kirill A. Shutemov + +commit 08529078d8d9adf689bf39cc38d53979a0869970 upstream. + +Prerequisite for fixing the current problem of instantaneous reboots when a +5-level paging kernel is booted on 4-level paging hardware. + +At the same time this change prepares the decompression code to boot-time +switching between 4- and 5-level paging. + +[ tglx: Folded the GCC < 5 fix. ] + +Fixes: 77ef56e4f0fb ("x86: Enable 5-level paging support via CONFIG_X86_5LEVEL=y") +Signed-off-by: Kirill A. Shutemov +Signed-off-by: Thomas Gleixner +Cc: Andi Kleen +Cc: Andy Lutomirski +Cc: linux-mm@kvack.org +Cc: Cyrill Gorcunov +Cc: Borislav Petkov +Cc: Linus Torvalds +Link: https://lkml.kernel.org/r/20171204124059.63515-2-kirill.shutemov@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/boot/compressed/Makefile | 1 + + arch/x86/boot/compressed/head_64.S | 16 ++++++++++++---- + arch/x86/boot/compressed/pgtable_64.c | 28 ++++++++++++++++++++++++++++ + 3 files changed, 41 insertions(+), 4 deletions(-) + +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -78,6 +78,7 @@ vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $ + vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o + ifdef CONFIG_X86_64 + vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/pagetable.o ++ vmlinux-objs-y += $(obj)/pgtable_64.o + endif + + $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone +--- a/arch/x86/boot/compressed/head_64.S ++++ b/arch/x86/boot/compressed/head_64.S +@@ -289,10 +289,18 @@ ENTRY(startup_64) + leaq boot_stack_end(%rbx), %rsp + + #ifdef CONFIG_X86_5LEVEL +- /* Check if 5-level paging has already enabled */ +- movq %cr4, %rax +- testl $X86_CR4_LA57, %eax +- jnz lvl5 ++ /* ++ * Check if we need to enable 5-level paging. ++ * RSI holds real mode data and need to be preserved across ++ * a function call. ++ */ ++ pushq %rsi ++ call l5_paging_required ++ popq %rsi ++ ++ /* If l5_paging_required() returned zero, we're done here. */ ++ cmpq $0, %rax ++ je lvl5 + + /* + * At this point we are in long mode with 4-level paging enabled, +--- /dev/null ++++ b/arch/x86/boot/compressed/pgtable_64.c +@@ -0,0 +1,28 @@ ++#include ++ ++/* ++ * __force_order is used by special_insns.h asm code to force instruction ++ * serialization. ++ * ++ * It is not referenced from the code, but GCC < 5 with -fPIE would fail ++ * due to an undefined symbol. Define it to make these ancient GCCs work. ++ */ ++unsigned long __force_order; ++ ++int l5_paging_required(void) ++{ ++ /* Check if leaf 7 is supported. */ ++ ++ if (native_cpuid_eax(0) < 7) ++ return 0; ++ ++ /* Check if la57 is supported. */ ++ if (!(native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) ++ return 0; ++ ++ /* Check if 5-level paging has already been enabled. */ ++ if (native_read_cr4() & X86_CR4_LA57) ++ return 0; ++ ++ return 1; ++} diff --git a/queue-4.14/x86-boot-compressed-64-print-error-if-5-level-paging-is-not-supported.patch b/queue-4.14/x86-boot-compressed-64-print-error-if-5-level-paging-is-not-supported.patch new file mode 100644 index 00000000000..cb284728dd7 --- /dev/null +++ b/queue-4.14/x86-boot-compressed-64-print-error-if-5-level-paging-is-not-supported.patch @@ -0,0 +1,68 @@ +From 6d7e0ba2d2be9e50cccba213baf07e0e183c1b24 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Mon, 4 Dec 2017 15:40:56 +0300 +Subject: x86/boot/compressed/64: Print error if 5-level paging is not supported + +From: Kirill A. Shutemov + +commit 6d7e0ba2d2be9e50cccba213baf07e0e183c1b24 upstream. + +If the machine does not support the paging mode for which the kernel was +compiled, the boot process cannot continue. + +It's not possible to let the kernel detect the mismatch as it does not even +reach the point where cpu features can be evaluted due to a triple fault in +the KASLR setup. + +Instead of instantaneous silent reboot, emit an error message which gives +the user the information why the boot fails. + +Fixes: 77ef56e4f0fb ("x86: Enable 5-level paging support via CONFIG_X86_5LEVEL=y") +Reported-by: Borislav Petkov +Signed-off-by: Kirill A. Shutemov +Signed-off-by: Thomas Gleixner +Tested-by: Borislav Petkov +Cc: Andi Kleen +Cc: Andy Lutomirski +Cc: linux-mm@kvack.org +Cc: Cyrill Gorcunov +Cc: Linus Torvalds +Link: https://lkml.kernel.org/r/20171204124059.63515-3-kirill.shutemov@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/boot/compressed/misc.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/arch/x86/boot/compressed/misc.c ++++ b/arch/x86/boot/compressed/misc.c +@@ -169,6 +169,16 @@ void __puthex(unsigned long value) + } + } + ++static bool l5_supported(void) ++{ ++ /* Check if leaf 7 is supported. */ ++ if (native_cpuid_eax(0) < 7) ++ return 0; ++ ++ /* Check if la57 is supported. */ ++ return native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)); ++} ++ + #if CONFIG_X86_NEED_RELOCS + static void handle_relocations(void *output, unsigned long output_len, + unsigned long virt_addr) +@@ -362,6 +372,12 @@ asmlinkage __visible void *extract_kerne + console_init(); + debug_putstr("early console in extract_kernel\n"); + ++ if (IS_ENABLED(CONFIG_X86_5LEVEL) && !l5_supported()) { ++ error("This linux kernel as configured requires 5-level paging\n" ++ "This CPU does not support the required 'cr4.la57' feature\n" ++ "Unable to boot - please use a kernel appropriate for your CPU\n"); ++ } ++ + free_mem_ptr = heap; /* Heap */ + free_mem_end_ptr = heap + BOOT_HEAP_SIZE; + diff --git a/queue-4.14/xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch b/queue-4.14/xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch new file mode 100644 index 00000000000..fa0ece7ae41 --- /dev/null +++ b/queue-4.14/xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch @@ -0,0 +1,62 @@ +From 5d9b70f7d52eb14bb37861c663bae44de9521c35 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Fri, 8 Dec 2017 18:10:05 +0200 +Subject: xhci: Don't add a virt_dev to the devs array before it's fully allocated + +From: Mathias Nyman + +commit 5d9b70f7d52eb14bb37861c663bae44de9521c35 upstream. + +Avoid null pointer dereference if some function is walking through the +devs array accessing members of a new virt_dev that is mid allocation. + +Add the virt_dev to xhci->devs[i] _after_ the virt_device and all its +members are properly allocated. + +issue found by KASAN: null-ptr-deref in xhci_find_slot_id_by_port + +"Quick analysis suggests that xhci_alloc_virt_device() is not mutex +protected. If so, there is a time frame where xhci->devs[slot_id] is set +but not fully initialized. Specifically, xhci->devs[i]->udev can be NULL." + +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -983,10 +983,9 @@ int xhci_alloc_virt_device(struct xhci_h + return 0; + } + +- xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags); +- if (!xhci->devs[slot_id]) ++ dev = kzalloc(sizeof(*dev), flags); ++ if (!dev) + return 0; +- dev = xhci->devs[slot_id]; + + /* Allocate the (output) device context that will be used in the HC. */ + dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags); +@@ -1027,9 +1026,17 @@ int xhci_alloc_virt_device(struct xhci_h + + trace_xhci_alloc_virt_device(dev); + ++ xhci->devs[slot_id] = dev; ++ + return 1; + fail: +- xhci_free_virt_device(xhci, slot_id); ++ ++ if (dev->in_ctx) ++ xhci_free_container_ctx(xhci, dev->in_ctx); ++ if (dev->out_ctx) ++ xhci_free_container_ctx(xhci, dev->out_ctx); ++ kfree(dev); ++ + return 0; + } +