From: Greg Kroah-Hartman Date: Fri, 24 Mar 2017 08:32:29 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.57~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2dc19fae3475b77d5e97da6b4b0badac60e36bec;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: nfs-prevent-double-free-in-async-nfs4_exchange_id.patch parisc-fix-system-shutdown-halt.patch parisc-optimize-flush_kernel_vmap_range-and-invalidate_kernel_vmap_range.patch perf-core-fix-event-inheritance-on-fork.patch perf-core-fix-use-after-free-in-perf_release.patch qla2xxx-fix-memory-leak-for-abts-processing.patch qla2xxx-fix-request-queue-corruption.patch xprtrdma-squelch-kbuild-sparse-complaint.patch --- diff --git a/queue-4.9/nfs-prevent-double-free-in-async-nfs4_exchange_id.patch b/queue-4.9/nfs-prevent-double-free-in-async-nfs4_exchange_id.patch new file mode 100644 index 00000000000..59f86726b69 --- /dev/null +++ b/queue-4.9/nfs-prevent-double-free-in-async-nfs4_exchange_id.patch @@ -0,0 +1,61 @@ +From 63513232f8cd219dcaa5eafae028740ed3067d83 Mon Sep 17 00:00:00 2001 +From: Olga Kornievskaia +Date: Mon, 13 Mar 2017 10:36:19 -0400 +Subject: NFS prevent double free in async nfs4_exchange_id + +From: Olga Kornievskaia + +commit 63513232f8cd219dcaa5eafae028740ed3067d83 upstream. + +Since rpc_task is async, the release function should be called which +will free the impl_id, scope, and owner. + +Trond pointed at 2 more problems: +-- use of client pointer after free in the nfs4_exchangeid_release() function +-- cl_count mismatch if rpc_run_task() isn't run + +Fixes: 8d89bd70bc9 ("NFS setup async exchange_id") +Signed-off-by: Olga Kornievskaia +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -7426,11 +7426,11 @@ static void nfs4_exchange_id_release(voi + struct nfs41_exchange_id_data *cdata = + (struct nfs41_exchange_id_data *)data; + +- nfs_put_client(cdata->args.client); + if (cdata->xprt) { + xprt_put(cdata->xprt); + rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient); + } ++ nfs_put_client(cdata->args.client); + kfree(cdata->res.impl_id); + kfree(cdata->res.server_scope); + kfree(cdata->res.server_owner); +@@ -7537,10 +7537,8 @@ static int _nfs4_proc_exchange_id(struct + task_setup_data.callback_data = calldata; + + task = rpc_run_task(&task_setup_data); +- if (IS_ERR(task)) { +- status = PTR_ERR(task); +- goto out_impl_id; +- } ++ if (IS_ERR(task)) ++ return PTR_ERR(task); + + if (!xprt) { + status = rpc_wait_for_completion_task(task); +@@ -7568,6 +7566,7 @@ out_server_owner: + kfree(calldata->res.server_owner); + out_calldata: + kfree(calldata); ++ nfs_put_client(clp); + goto out; + } + diff --git a/queue-4.9/parisc-fix-system-shutdown-halt.patch b/queue-4.9/parisc-fix-system-shutdown-halt.patch new file mode 100644 index 00000000000..b26ea20f37c --- /dev/null +++ b/queue-4.9/parisc-fix-system-shutdown-halt.patch @@ -0,0 +1,32 @@ +From 73580dac7618e4bcd21679f553cf3c97323fec46 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Sat, 18 Mar 2017 17:13:27 +0100 +Subject: parisc: Fix system shutdown halt + +From: Helge Deller + +commit 73580dac7618e4bcd21679f553cf3c97323fec46 upstream. + +On those parisc machines which don't provide a software power off +function, the system currently kills the init process at the end of a +shutdown and unexpectedly restarts insteads of halting. +Fix it by adding a loop which will not return. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/process.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/parisc/kernel/process.c ++++ b/arch/parisc/kernel/process.c +@@ -139,6 +139,8 @@ void machine_power_off(void) + + printk(KERN_EMERG "System shut down completed.\n" + "Please power this system off now."); ++ ++ for (;;); + } + + void (*pm_power_off)(void) = machine_power_off; diff --git a/queue-4.9/parisc-optimize-flush_kernel_vmap_range-and-invalidate_kernel_vmap_range.patch b/queue-4.9/parisc-optimize-flush_kernel_vmap_range-and-invalidate_kernel_vmap_range.patch new file mode 100644 index 00000000000..6d7424dd128 --- /dev/null +++ b/queue-4.9/parisc-optimize-flush_kernel_vmap_range-and-invalidate_kernel_vmap_range.patch @@ -0,0 +1,90 @@ +From 316ec0624f951166daedbe446988ef92ae72b59f Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Sat, 11 Mar 2017 18:03:34 -0500 +Subject: parisc: Optimize flush_kernel_vmap_range and invalidate_kernel_vmap_range + +From: John David Anglin + +commit 316ec0624f951166daedbe446988ef92ae72b59f upstream. + +The previously submitted patch did not resolve the random segmentation +faults observed on the phantom buildd system. There are still +unresolved problems with the Debian 4.8 and 4.9 kernels on C8000. + +The attached patch removes the flush of the offset map pages and does a +whole data cache flush for large ranges. No other arch flushes the +offset map in these routines as far as I can tell. + +I have not observed any random segmentation faults on rp3440 in two +weeks of testing with 4.10.0 and 4.10.1. + +Signed-off-by: John David Anglin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/cacheflush.h | 23 ++--------------------- + arch/parisc/kernel/cache.c | 22 ++++++++++++++++++++++ + 2 files changed, 24 insertions(+), 21 deletions(-) + +--- a/arch/parisc/include/asm/cacheflush.h ++++ b/arch/parisc/include/asm/cacheflush.h +@@ -45,28 +45,9 @@ static inline void flush_kernel_dcache_p + + #define flush_kernel_dcache_range(start,size) \ + flush_kernel_dcache_range_asm((start), (start)+(size)); +-/* vmap range flushes and invalidates. Architecturally, we don't need +- * the invalidate, because the CPU should refuse to speculate once an +- * area has been flushed, so invalidate is left empty */ +-static inline void flush_kernel_vmap_range(void *vaddr, int size) +-{ +- unsigned long start = (unsigned long)vaddr; + +- flush_kernel_dcache_range_asm(start, start + size); +-} +-static inline void invalidate_kernel_vmap_range(void *vaddr, int size) +-{ +- unsigned long start = (unsigned long)vaddr; +- void *cursor = vaddr; +- +- for ( ; cursor < vaddr + size; cursor += PAGE_SIZE) { +- struct page *page = vmalloc_to_page(cursor); +- +- if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) +- flush_kernel_dcache_page(page); +- } +- flush_kernel_dcache_range_asm(start, start + size); +-} ++void flush_kernel_vmap_range(void *vaddr, int size); ++void invalidate_kernel_vmap_range(void *vaddr, int size); + + #define flush_cache_vmap(start, end) flush_cache_all() + #define flush_cache_vunmap(start, end) flush_cache_all() +--- a/arch/parisc/kernel/cache.c ++++ b/arch/parisc/kernel/cache.c +@@ -633,3 +633,25 @@ flush_cache_page(struct vm_area_struct * + __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); + } + } ++ ++void flush_kernel_vmap_range(void *vaddr, int size) ++{ ++ unsigned long start = (unsigned long)vaddr; ++ ++ if ((unsigned long)size > parisc_cache_flush_threshold) ++ flush_data_cache(); ++ else ++ flush_kernel_dcache_range_asm(start, start + size); ++} ++EXPORT_SYMBOL(flush_kernel_vmap_range); ++ ++void invalidate_kernel_vmap_range(void *vaddr, int size) ++{ ++ unsigned long start = (unsigned long)vaddr; ++ ++ if ((unsigned long)size > parisc_cache_flush_threshold) ++ flush_data_cache(); ++ else ++ flush_kernel_dcache_range_asm(start, start + size); ++} ++EXPORT_SYMBOL(invalidate_kernel_vmap_range); diff --git a/queue-4.9/perf-core-fix-event-inheritance-on-fork.patch b/queue-4.9/perf-core-fix-event-inheritance-on-fork.patch new file mode 100644 index 00000000000..3aeb1e6a183 --- /dev/null +++ b/queue-4.9/perf-core-fix-event-inheritance-on-fork.patch @@ -0,0 +1,66 @@ +From e7cc4865f0f31698ef2f7aac01a50e78968985b7 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Thu, 16 Mar 2017 13:47:49 +0100 +Subject: perf/core: Fix event inheritance on fork() + +From: Peter Zijlstra + +commit e7cc4865f0f31698ef2f7aac01a50e78968985b7 upstream. + +While hunting for clues to a use-after-free, Oleg spotted that +perf_event_init_context() can loose an error value with the result +that fork() can succeed even though we did not fully inherit the perf +event context. + +Spotted-by: Oleg Nesterov +Signed-off-by: Peter Zijlstra (Intel) +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Arnaldo Carvalho de Melo +Cc: Dmitry Vyukov +Cc: Frederic Weisbecker +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Mathieu Desnoyers +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Cc: oleg@redhat.com +Fixes: 889ff0150661 ("perf/core: Split context's event group list into pinned and non-pinned lists") +Link: http://lkml.kernel.org/r/20170316125823.190342547@infradead.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -10597,7 +10597,7 @@ static int perf_event_init_context(struc + ret = inherit_task_group(event, parent, parent_ctx, + child, ctxn, &inherited_all); + if (ret) +- break; ++ goto out_unlock; + } + + /* +@@ -10613,7 +10613,7 @@ static int perf_event_init_context(struc + ret = inherit_task_group(event, parent, parent_ctx, + child, ctxn, &inherited_all); + if (ret) +- break; ++ goto out_unlock; + } + + raw_spin_lock_irqsave(&parent_ctx->lock, flags); +@@ -10641,6 +10641,7 @@ static int perf_event_init_context(struc + } + + raw_spin_unlock_irqrestore(&parent_ctx->lock, flags); ++out_unlock: + mutex_unlock(&parent_ctx->mutex); + + perf_unpin_context(parent_ctx); diff --git a/queue-4.9/perf-core-fix-use-after-free-in-perf_release.patch b/queue-4.9/perf-core-fix-use-after-free-in-perf_release.patch new file mode 100644 index 00000000000..aa7a759f2ff --- /dev/null +++ b/queue-4.9/perf-core-fix-use-after-free-in-perf_release.patch @@ -0,0 +1,99 @@ +From e552a8389aa409e257b7dcba74f67f128f979ccc Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Thu, 16 Mar 2017 13:47:48 +0100 +Subject: perf/core: Fix use-after-free in perf_release() + +From: Peter Zijlstra + +commit e552a8389aa409e257b7dcba74f67f128f979ccc upstream. + +Dmitry reported syzcaller tripped a use-after-free in perf_release(). + +After much puzzlement Oleg spotted the below scenario: + + Task1 Task2 + + fork() + perf_event_init_task() + /* ... */ + goto bad_fork_$foo; + /* ... */ + perf_event_free_task() + mutex_lock(ctx->lock) + perf_free_event(B) + + perf_event_release_kernel(A) + mutex_lock(A->child_mutex) + list_for_each_entry(child, ...) { + /* child == B */ + ctx = B->ctx; + get_ctx(ctx); + mutex_unlock(A->child_mutex); + + mutex_lock(A->child_mutex) + list_del_init(B->child_list) + mutex_unlock(A->child_mutex) + + /* ... */ + + mutex_unlock(ctx->lock); + put_ctx() /* >0 */ + free_task(); + mutex_lock(ctx->lock); + mutex_lock(A->child_mutex); + /* ... */ + mutex_unlock(A->child_mutex); + mutex_unlock(ctx->lock) + put_ctx() /* 0 */ + ctx->task && !TOMBSTONE + put_task_struct() /* UAF */ + +This patch closes the hole by making perf_event_free_task() destroy the +task <-> ctx relation such that perf_event_release_kernel() will no longer +observe the now dead task. + +Spotted-by: Oleg Nesterov +Reported-by: Dmitry Vyukov +Signed-off-by: Peter Zijlstra (Intel) +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Mathieu Desnoyers +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Cc: fweisbec@gmail.com +Cc: oleg@redhat.com +Fixes: c6e5b73242d2 ("perf: Synchronously clean up child events") +Link: http://lkml.kernel.org/r/20170314155949.GE32474@worktop +Link: http://lkml.kernel.org/r/20170316125823.140295131@infradead.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/core.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -10333,6 +10333,17 @@ void perf_event_free_task(struct task_st + continue; + + mutex_lock(&ctx->mutex); ++ raw_spin_lock_irq(&ctx->lock); ++ /* ++ * Destroy the task <-> ctx relation and mark the context dead. ++ * ++ * This is important because even though the task hasn't been ++ * exposed yet the context has been (through child_list). ++ */ ++ RCU_INIT_POINTER(task->perf_event_ctxp[ctxn], NULL); ++ WRITE_ONCE(ctx->task, TASK_TOMBSTONE); ++ put_task_struct(task); /* cannot be last */ ++ raw_spin_unlock_irq(&ctx->lock); + again: + list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, + group_entry) diff --git a/queue-4.9/qla2xxx-fix-memory-leak-for-abts-processing.patch b/queue-4.9/qla2xxx-fix-memory-leak-for-abts-processing.patch new file mode 100644 index 00000000000..0a74b3de1bf --- /dev/null +++ b/queue-4.9/qla2xxx-fix-memory-leak-for-abts-processing.patch @@ -0,0 +1,29 @@ +From ae940f2c472a62904dc18234de5cf3ed28f195ee Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Wed, 15 Mar 2017 09:48:44 -0700 +Subject: qla2xxx: Fix memory leak for abts processing + +From: Quinn Tran + +commit ae940f2c472a62904dc18234de5cf3ed28f195ee upstream. + +Signed-off-by: Quinn Tran +Signed-off-by: Himanshu Madhani +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_target.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -6794,6 +6794,8 @@ qlt_handle_abts_recv_work(struct work_st + spin_lock_irqsave(&ha->hardware_lock, flags); + qlt_response_pkt_all_vps(vha, (response_t *)&op->atio); + spin_unlock_irqrestore(&ha->hardware_lock, flags); ++ ++ kfree(op); + } + + void diff --git a/queue-4.9/qla2xxx-fix-request-queue-corruption.patch b/queue-4.9/qla2xxx-fix-request-queue-corruption.patch new file mode 100644 index 00000000000..6ce560b4ea7 --- /dev/null +++ b/queue-4.9/qla2xxx-fix-request-queue-corruption.patch @@ -0,0 +1,66 @@ +From 8b666809e10cda9814af3e8be339d35b83909056 Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Wed, 15 Mar 2017 09:48:45 -0700 +Subject: qla2xxx: Fix request queue corruption. + +From: Quinn Tran + +commit 8b666809e10cda9814af3e8be339d35b83909056 upstream. + +When FW notify driver or driver detects low FW resource, +driver tries to send out Busy SCSI Status to tell Initiator +side to back off. During the send process, the lock was not held. + +Signed-off-by: Quinn Tran +Signed-off-by: Himanshu Madhani +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_target.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -5375,16 +5375,22 @@ qlt_send_busy(struct scsi_qla_host *vha, + + static int + qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, +- struct atio_from_isp *atio) ++ struct atio_from_isp *atio, bool ha_locked) + { + struct qla_hw_data *ha = vha->hw; + uint16_t status; ++ unsigned long flags; + + if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha)) + return 0; + ++ if (!ha_locked) ++ spin_lock_irqsave(&ha->hardware_lock, flags); + status = temp_sam_status; + qlt_send_busy(vha, atio, status); ++ if (!ha_locked) ++ spin_unlock_irqrestore(&ha->hardware_lock, flags); ++ + return 1; + } + +@@ -5429,7 +5435,7 @@ static void qlt_24xx_atio_pkt(struct scs + + + if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) { +- rc = qlt_chk_qfull_thresh_hold(vha, atio); ++ rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked); + if (rc != 0) { + tgt->atio_irq_cmd_count--; + return; +@@ -5552,7 +5558,7 @@ static void qlt_response_pkt(struct scsi + break; + } + +- rc = qlt_chk_qfull_thresh_hold(vha, atio); ++ rc = qlt_chk_qfull_thresh_hold(vha, atio, true); + if (rc != 0) { + tgt->irq_cmd_count--; + return; diff --git a/queue-4.9/series b/queue-4.9/series index b4561239c8c..d1546f6956f 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -1,3 +1,11 @@ drm-vc4-fix-termination-of-the-initial-scan-for-branch-targets.patch drm-vc4-use-runtime-autosuspend-to-avoid-thrashing-v3d-power-state.patch give-up-on-gcc-ilog2-constant-optimizations.patch +qla2xxx-fix-memory-leak-for-abts-processing.patch +qla2xxx-fix-request-queue-corruption.patch +parisc-optimize-flush_kernel_vmap_range-and-invalidate_kernel_vmap_range.patch +parisc-fix-system-shutdown-halt.patch +perf-core-fix-use-after-free-in-perf_release.patch +perf-core-fix-event-inheritance-on-fork.patch +xprtrdma-squelch-kbuild-sparse-complaint.patch +nfs-prevent-double-free-in-async-nfs4_exchange_id.patch diff --git a/queue-4.9/xprtrdma-squelch-kbuild-sparse-complaint.patch b/queue-4.9/xprtrdma-squelch-kbuild-sparse-complaint.patch new file mode 100644 index 00000000000..59c1c711155 --- /dev/null +++ b/queue-4.9/xprtrdma-squelch-kbuild-sparse-complaint.patch @@ -0,0 +1,45 @@ +From eed50879d64ab1b9f76445dbab822e43a098b309 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Sat, 11 Mar 2017 15:52:47 -0500 +Subject: xprtrdma: Squelch kbuild sparse complaint + +From: Chuck Lever + +commit eed50879d64ab1b9f76445dbab822e43a098b309 upstream. + +New complaint from kbuild for 4.9.y: + +net/sunrpc/xprtrdma/verbs.c:489:19: sparse: incompatible types in + comparison expression (different type sizes) + +verbs.c: +489 max_sge = min(ia->ri_device->attrs.max_sge, RPCRDMA_MAX_SEND_SGES); + +I can't reproduce this running sparse here. Likewise, "make W=1 +net/sunrpc/xprtrdma/verbs.o" never indicated any issue. + +A little poking suggests that because the range of its values is +small, gcc can make the actual width of RPCRDMA_MAX_SEND_SGES +smaller than the width of an unsigned integer. + +Fixes: 16f906d66cd7 ("xprtrdma: Reduce required number of send SGEs") +Signed-off-by: Chuck Lever +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/xprtrdma/verbs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/sunrpc/xprtrdma/verbs.c ++++ b/net/sunrpc/xprtrdma/verbs.c +@@ -486,7 +486,8 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, + struct ib_cq *sendcq, *recvcq; + int rc; + +- max_sge = min(ia->ri_device->attrs.max_sge, RPCRDMA_MAX_SEND_SGES); ++ max_sge = min_t(unsigned int, ia->ri_device->attrs.max_sge, ++ RPCRDMA_MAX_SEND_SGES); + if (max_sge < RPCRDMA_MIN_SEND_SGES) { + pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge); + return -ENOMEM;