From: Greg Kroah-Hartman Date: Sat, 8 Aug 2015 22:00:25 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v4.1.5~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1e5b1a475aeb3e836d514ea517bd44211f2f7089;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: avr32-handle-null-as-a-valid-clock-object.patch iscsi-target-fix-iser-explicit-logout-tx-kthread-leak.patch iscsi-target-fix-use-after-free-during-tpg-session-shutdown.patch rds-rds_ib_device.refcount-overflow.patch vhost-actually-track-log-eventfd-file.patch --- diff --git a/queue-3.14/avr32-handle-null-as-a-valid-clock-object.patch b/queue-3.14/avr32-handle-null-as-a-valid-clock-object.patch new file mode 100644 index 00000000000..adca0590024 --- /dev/null +++ b/queue-3.14/avr32-handle-null-as-a-valid-clock-object.patch @@ -0,0 +1,92 @@ +From 5c02a4206538da12c040b51778d310df84c6bf6c Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Fri, 24 Jul 2015 13:49:48 +0300 +Subject: avr32: handle NULL as a valid clock object + +From: Andy Shevchenko + +commit 5c02a4206538da12c040b51778d310df84c6bf6c upstream. + +Since NULL is used as valid clock object on optional clocks we have to handle +this case in avr32 implementation as well. + +Fixes: e1824dfe0d8e (net: macb: Adjust tx_clk when link speed changes) +Signed-off-by: Andy Shevchenko +Acked-by: Hans-Christian Egtvedt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/avr32/mach-at32ap/clock.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +--- a/arch/avr32/mach-at32ap/clock.c ++++ b/arch/avr32/mach-at32ap/clock.c +@@ -80,6 +80,9 @@ int clk_enable(struct clk *clk) + { + unsigned long flags; + ++ if (!clk) ++ return 0; ++ + spin_lock_irqsave(&clk_lock, flags); + __clk_enable(clk); + spin_unlock_irqrestore(&clk_lock, flags); +@@ -106,6 +109,9 @@ void clk_disable(struct clk *clk) + { + unsigned long flags; + ++ if (IS_ERR_OR_NULL(clk)) ++ return; ++ + spin_lock_irqsave(&clk_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clk_lock, flags); +@@ -117,6 +123,9 @@ unsigned long clk_get_rate(struct clk *c + unsigned long flags; + unsigned long rate; + ++ if (!clk) ++ return 0; ++ + spin_lock_irqsave(&clk_lock, flags); + rate = clk->get_rate(clk); + spin_unlock_irqrestore(&clk_lock, flags); +@@ -129,6 +138,9 @@ long clk_round_rate(struct clk *clk, uns + { + unsigned long flags, actual_rate; + ++ if (!clk) ++ return 0; ++ + if (!clk->set_rate) + return -ENOSYS; + +@@ -145,6 +157,9 @@ int clk_set_rate(struct clk *clk, unsign + unsigned long flags; + long ret; + ++ if (!clk) ++ return 0; ++ + if (!clk->set_rate) + return -ENOSYS; + +@@ -161,6 +176,9 @@ int clk_set_parent(struct clk *clk, stru + unsigned long flags; + int ret; + ++ if (!clk) ++ return 0; ++ + if (!clk->set_parent) + return -ENOSYS; + +@@ -174,7 +192,7 @@ EXPORT_SYMBOL(clk_set_parent); + + struct clk *clk_get_parent(struct clk *clk) + { +- return clk->parent; ++ return !clk ? NULL : clk->parent; + } + EXPORT_SYMBOL(clk_get_parent); + diff --git a/queue-3.14/iscsi-target-fix-iser-explicit-logout-tx-kthread-leak.patch b/queue-3.14/iscsi-target-fix-iser-explicit-logout-tx-kthread-leak.patch new file mode 100644 index 00000000000..7af3a576c1f --- /dev/null +++ b/queue-3.14/iscsi-target-fix-iser-explicit-logout-tx-kthread-leak.patch @@ -0,0 +1,71 @@ +From 007d038bdf95ccfe2491d0078be54040d110fd06 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 23 Jul 2015 22:30:31 +0000 +Subject: iscsi-target: Fix iser explicit logout TX kthread leak + +From: Nicholas Bellinger + +commit 007d038bdf95ccfe2491d0078be54040d110fd06 upstream. + +This patch fixes a regression introduced with the following commit +in v4.0-rc1 code, where an explicit iser-target logout would result +in ->tx_thread_active being incorrectly cleared by the logout post +handler, and subsequent TX kthread leak: + + commit 88dcd2dab5c23b1c9cfc396246d8f476c872f0ca + Author: Nicholas Bellinger + Date: Thu Feb 26 22:19:15 2015 -0800 + + iscsi-target: Convert iscsi_thread_set usage to kthread.h + +To address this bug, change iscsit_logout_post_handler_closesession() +and iscsit_logout_post_handler_samecid() to only cmpxchg() on +->tx_thread_active for traditional iscsi/tcp connections. + +This is required because iscsi/tcp connections are invoking logout +post handler logic directly from TX kthread context, while iser +connections are invoking logout post handler logic from a seperate +workqueue context. + +Cc: Sagi Grimberg +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4476,7 +4476,18 @@ static void iscsit_logout_post_handler_c + struct iscsi_conn *conn) + { + struct iscsi_session *sess = conn->sess; +- int sleep = cmpxchg(&conn->tx_thread_active, true, false); ++ int sleep = 1; ++ /* ++ * Traditional iscsi/tcp will invoke this logic from TX thread ++ * context during session logout, so clear tx_thread_active and ++ * sleep if iscsit_close_connection() has not already occured. ++ * ++ * Since iser-target invokes this logic from it's own workqueue, ++ * always sleep waiting for RX/TX thread shutdown to complete ++ * within iscsit_close_connection(). ++ */ ++ if (conn->conn_transport->transport_type == ISCSI_TCP) ++ sleep = cmpxchg(&conn->tx_thread_active, true, false); + + atomic_set(&conn->conn_logout_remove, 0); + complete(&conn->conn_logout_comp); +@@ -4490,7 +4501,10 @@ static void iscsit_logout_post_handler_c + static void iscsit_logout_post_handler_samecid( + struct iscsi_conn *conn) + { +- int sleep = cmpxchg(&conn->tx_thread_active, true, false); ++ int sleep = 1; ++ ++ if (conn->conn_transport->transport_type == ISCSI_TCP) ++ sleep = cmpxchg(&conn->tx_thread_active, true, false); + + atomic_set(&conn->conn_logout_remove, 0); + complete(&conn->conn_logout_comp); diff --git a/queue-3.14/iscsi-target-fix-use-after-free-during-tpg-session-shutdown.patch b/queue-3.14/iscsi-target-fix-use-after-free-during-tpg-session-shutdown.patch new file mode 100644 index 00000000000..2863928d320 --- /dev/null +++ b/queue-3.14/iscsi-target-fix-use-after-free-during-tpg-session-shutdown.patch @@ -0,0 +1,65 @@ +From 417c20a9bdd1e876384127cf096d8ae8b559066c Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 22 Jul 2015 00:24:09 -0700 +Subject: iscsi-target: Fix use-after-free during TPG session shutdown + +From: Nicholas Bellinger + +commit 417c20a9bdd1e876384127cf096d8ae8b559066c upstream. + +This patch fixes a use-after-free bug in iscsit_release_sessions_for_tpg() +where se_portal_group->session_lock was incorrectly released/re-acquired +while walking the active se_portal_group->tpg_sess_list. + +The can result in a NULL pointer dereference when iscsit_close_session() +shutdown happens in the normal path asynchronously to this code, causing +a bogus dereference of an already freed list entry to occur. + +To address this bug, walk the session list checking for the same state +as before, but move entries to a local list to avoid dropping the lock +while walking the active list. + +As before, signal using iscsi_session->session_restatement=1 for those +list entries to be released locally by iscsit_free_session() code. + +Reported-by: Sunilkumar Nadumuttlu +Cc: Sunilkumar Nadumuttlu +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4709,6 +4709,7 @@ int iscsit_release_sessions_for_tpg(stru + struct iscsi_session *sess; + struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; + struct se_session *se_sess, *se_sess_tmp; ++ LIST_HEAD(free_list); + int session_count = 0; + + spin_lock_bh(&se_tpg->session_lock); +@@ -4730,14 +4731,17 @@ int iscsit_release_sessions_for_tpg(stru + } + atomic_set(&sess->session_reinstatement, 1); + spin_unlock(&sess->conn_lock); +- spin_unlock_bh(&se_tpg->session_lock); + +- iscsit_free_session(sess); +- spin_lock_bh(&se_tpg->session_lock); ++ list_move_tail(&se_sess->sess_list, &free_list); ++ } ++ spin_unlock_bh(&se_tpg->session_lock); + ++ list_for_each_entry_safe(se_sess, se_sess_tmp, &free_list, sess_list) { ++ sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; ++ ++ iscsit_free_session(sess); + session_count++; + } +- spin_unlock_bh(&se_tpg->session_lock); + + pr_debug("Released %d iSCSI Session(s) from Target Portal" + " Group: %hu\n", session_count, tpg->tpgt); diff --git a/queue-3.14/rds-rds_ib_device.refcount-overflow.patch b/queue-3.14/rds-rds_ib_device.refcount-overflow.patch new file mode 100644 index 00000000000..fc57e0bf20b --- /dev/null +++ b/queue-3.14/rds-rds_ib_device.refcount-overflow.patch @@ -0,0 +1,51 @@ +From 4fabb59449aa44a585b3603ffdadd4c5f4d0c033 Mon Sep 17 00:00:00 2001 +From: Wengang Wang +Date: Mon, 6 Jul 2015 14:35:11 +0800 +Subject: rds: rds_ib_device.refcount overflow + +From: Wengang Wang + +commit 4fabb59449aa44a585b3603ffdadd4c5f4d0c033 upstream. + +Fixes: 3e0249f9c05c ("RDS/IB: add refcount tracking to struct rds_ib_device") + +There lacks a dropping on rds_ib_device.refcount in case rds_ib_alloc_fmr +failed(mr pool running out). this lead to the refcount overflow. + +A complain in line 117(see following) is seen. From vmcore: +s_ib_rdma_mr_pool_depleted is 2147485544 and rds_ibdev->refcount is -2147475448. +That is the evidence the mr pool is used up. so rds_ib_alloc_fmr is very likely +to return ERR_PTR(-EAGAIN). + +115 void rds_ib_dev_put(struct rds_ib_device *rds_ibdev) +116 { +117 BUG_ON(atomic_read(&rds_ibdev->refcount) <= 0); +118 if (atomic_dec_and_test(&rds_ibdev->refcount)) +119 queue_work(rds_wq, &rds_ibdev->free_work); +120 } + +fix is to drop refcount when rds_ib_alloc_fmr failed. + +Signed-off-by: Wengang Wang +Reviewed-by: Haggai Eran +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + net/rds/ib_rdma.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/rds/ib_rdma.c ++++ b/net/rds/ib_rdma.c +@@ -759,8 +759,10 @@ void *rds_ib_get_mr(struct scatterlist * + } + + ibmr = rds_ib_alloc_fmr(rds_ibdev); +- if (IS_ERR(ibmr)) ++ if (IS_ERR(ibmr)) { ++ rds_ib_dev_put(rds_ibdev); + return ibmr; ++ } + + ret = rds_ib_map_fmr(rds_ibdev, ibmr, sg, nents); + if (ret == 0) diff --git a/queue-3.14/series b/queue-3.14/series index a0f404877da..681758b69d4 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -21,3 +21,8 @@ xhci-report-u3-when-link-is-in-resume-state.patch xhci-prevent-bus_suspend-if-ss-port-resuming-in-phase-1.patch xhci-do-not-report-plc-when-link-is-in-internal-resume-state.patch x86-efi-use-all-64-bit-of-efi_memmap-in-setup_e820.patch +rds-rds_ib_device.refcount-overflow.patch +vhost-actually-track-log-eventfd-file.patch +avr32-handle-null-as-a-valid-clock-object.patch +iscsi-target-fix-use-after-free-during-tpg-session-shutdown.patch +iscsi-target-fix-iser-explicit-logout-tx-kthread-leak.patch diff --git a/queue-3.14/vhost-actually-track-log-eventfd-file.patch b/queue-3.14/vhost-actually-track-log-eventfd-file.patch new file mode 100644 index 00000000000..058e12c5a65 --- /dev/null +++ b/queue-3.14/vhost-actually-track-log-eventfd-file.patch @@ -0,0 +1,33 @@ +From 7932c0bd7740f4cd2aa168d3ce0199e7af7d72d5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 17 Jul 2015 15:32:03 +0200 +Subject: vhost: actually track log eventfd file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= + +commit 7932c0bd7740f4cd2aa168d3ce0199e7af7d72d5 upstream. + +While reviewing vhost log code, I found out that log_file is never +set. Note: I haven't tested the change (QEMU doesn't use LOG_FD yet). + +Signed-off-by: Marc-André Lureau +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/vhost/vhost.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -876,6 +876,7 @@ long vhost_dev_ioctl(struct vhost_dev *d + } + if (eventfp != d->log_file) { + filep = d->log_file; ++ d->log_file = eventfp; + ctx = d->log_ctx; + d->log_ctx = eventfp ? + eventfd_ctx_fileget(eventfp) : NULL;