]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jun 2014 22:10:54 +0000 (15:10 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jun 2014 22:10:54 +0000 (15:10 -0700)
added patches:
iscsi-target-fix-wrong-buffer-buffer-overrun-in-iscsi_change_param_value.patch
iser-target-add-missing-target_put_sess_cmd-for-immedatedata-failure.patch
mm-add-pte_present-check-on-existing-hugetlb_entry-callbacks.patch
mm-rmap-fix-use-after-free-in-__put_anon_vma.patch
target-fix-alua_access_state-attribute-oops-for-un-configured-devices.patch

queue-3.14/iscsi-target-fix-wrong-buffer-buffer-overrun-in-iscsi_change_param_value.patch [new file with mode: 0644]
queue-3.14/iser-target-add-missing-target_put_sess_cmd-for-immedatedata-failure.patch [new file with mode: 0644]
queue-3.14/mm-add-pte_present-check-on-existing-hugetlb_entry-callbacks.patch [new file with mode: 0644]
queue-3.14/mm-rmap-fix-use-after-free-in-__put_anon_vma.patch [new file with mode: 0644]
queue-3.14/series
queue-3.14/target-fix-alua_access_state-attribute-oops-for-un-configured-devices.patch [new file with mode: 0644]

diff --git a/queue-3.14/iscsi-target-fix-wrong-buffer-buffer-overrun-in-iscsi_change_param_value.patch b/queue-3.14/iscsi-target-fix-wrong-buffer-buffer-overrun-in-iscsi_change_param_value.patch
new file mode 100644 (file)
index 0000000..41c2d6b
--- /dev/null
@@ -0,0 +1,145 @@
+From 79d59d08082dd0a0a18f8ceb78c99f9f321d72aa Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland@purestorage.com>
+Date: Thu, 29 May 2014 13:32:30 -0700
+Subject: iscsi-target: Fix wrong buffer / buffer overrun in iscsi_change_param_value()
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 79d59d08082dd0a0a18f8ceb78c99f9f321d72aa upstream.
+
+In non-leading connection login, iscsi_login_non_zero_tsih_s1() calls
+iscsi_change_param_value() with the buffer it uses to hold the login
+PDU, not a temporary buffer.  This leads to the login header getting
+corrupted and login failing for non-leading connections in MC/S.
+
+Fix this by adding a wrapper iscsi_change_param_sprintf() that handles
+the temporary buffer itself to avoid confusion.  Also handle sending a
+reject in case of failure in the wrapper, which lets the calling code
+get quite a bit smaller and easier to read.
+
+Finally, bump the size of the temporary buffer from 32 to 64 bytes to be
+safe, since "MaxRecvDataSegmentLength=" by itself is 25 bytes; with a
+trailing NUL, a value >= 1M will lead to a buffer overrun.  (This isn't
+the default but we don't need to run right at the ragged edge here)
+
+Reported-by: Santosh Kulkarni <santosh.kulkarni@calsoftinc.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target_login.c |   57 ++++++++++++++----------------
+ 1 file changed, 28 insertions(+), 29 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -249,6 +249,28 @@ static void iscsi_login_set_conn_values(
+       mutex_unlock(&auth_id_lock);
+ }
++static __printf(2, 3) int iscsi_change_param_sprintf(
++      struct iscsi_conn *conn,
++      const char *fmt, ...)
++{
++      va_list args;
++      unsigned char buf[64];
++
++      memset(buf, 0, sizeof buf);
++
++      va_start(args, fmt);
++      vsnprintf(buf, sizeof buf, fmt, args);
++      va_end(args);
++
++      if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
++              iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
++                              ISCSI_LOGIN_STATUS_NO_RESOURCES);
++              return -1;
++      }
++
++      return 0;
++}
++
+ /*
+  *    This is the leading connection of a new session,
+  *    or session reinstatement.
+@@ -337,7 +359,6 @@ static int iscsi_login_zero_tsih_s2(
+ {
+       struct iscsi_node_attrib *na;
+       struct iscsi_session *sess = conn->sess;
+-      unsigned char buf[32];
+       bool iser = false;
+       sess->tpg = conn->tpg;
+@@ -378,26 +399,16 @@ static int iscsi_login_zero_tsih_s2(
+        *
+        * In our case, we have already located the struct iscsi_tiqn at this point.
+        */
+-      memset(buf, 0, 32);
+-      sprintf(buf, "TargetPortalGroupTag=%hu", sess->tpg->tpgt);
+-      if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+-              iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+-                              ISCSI_LOGIN_STATUS_NO_RESOURCES);
++      if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", sess->tpg->tpgt))
+               return -1;
+-      }
+       /*
+        * Workaround for Initiators that have broken connection recovery logic.
+        *
+        * "We would really like to get rid of this." Linux-iSCSI.org team
+        */
+-      memset(buf, 0, 32);
+-      sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl);
+-      if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+-              iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+-                              ISCSI_LOGIN_STATUS_NO_RESOURCES);
++      if (iscsi_change_param_sprintf(conn, "ErrorRecoveryLevel=%d", na->default_erl))
+               return -1;
+-      }
+       if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
+               return -1;
+@@ -409,12 +420,9 @@ static int iscsi_login_zero_tsih_s2(
+               unsigned long mrdsl, off;
+               int rc;
+-              sprintf(buf, "RDMAExtensions=Yes");
+-              if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+-                      iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+-                              ISCSI_LOGIN_STATUS_NO_RESOURCES);
++              if (iscsi_change_param_sprintf(conn, "RDMAExtensions=Yes"))
+                       return -1;
+-              }
++
+               /*
+                * Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
+                * Immediate Data + Unsolicitied Data-OUT if necessary..
+@@ -444,12 +452,8 @@ static int iscsi_login_zero_tsih_s2(
+               pr_warn("Aligning ISER MaxRecvDataSegmentLength: %lu down"
+                       " to PAGE_SIZE\n", mrdsl);
+-              sprintf(buf, "MaxRecvDataSegmentLength=%lu\n", mrdsl);
+-              if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+-                      iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+-                              ISCSI_LOGIN_STATUS_NO_RESOURCES);
++              if (iscsi_change_param_sprintf(conn, "MaxRecvDataSegmentLength=%lu\n", mrdsl))
+                       return -1;
+-              }
+       }
+       return 0;
+@@ -591,13 +595,8 @@ static int iscsi_login_non_zero_tsih_s2(
+        *
+        * In our case, we have already located the struct iscsi_tiqn at this point.
+        */
+-      memset(buf, 0, 32);
+-      sprintf(buf, "TargetPortalGroupTag=%hu", sess->tpg->tpgt);
+-      if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+-              iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+-                              ISCSI_LOGIN_STATUS_NO_RESOURCES);
++      if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", sess->tpg->tpgt))
+               return -1;
+-      }
+       return iscsi_login_disable_FIM_keys(conn->param_list, conn);
+ }
diff --git a/queue-3.14/iser-target-add-missing-target_put_sess_cmd-for-immedatedata-failure.patch b/queue-3.14/iser-target-add-missing-target_put_sess_cmd-for-immedatedata-failure.patch
new file mode 100644 (file)
index 0000000..d670fee
--- /dev/null
@@ -0,0 +1,43 @@
+From 6cc44a6fb46e1ecc1c28125aa8fa34d317aa9ea7 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Fri, 23 May 2014 00:48:35 -0700
+Subject: iser-target: Add missing target_put_sess_cmd for ImmedateData failure
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 6cc44a6fb46e1ecc1c28125aa8fa34d317aa9ea7 upstream.
+
+This patch addresses a bug where an early exception for SCSI WRITE
+with ImmediateData=Yes was missing the target_put_sess_cmd() call
+to drop the extra se_cmd->cmd_kref reference obtained during the
+normal iscsit_setup_scsi_cmd() codepath execution.
+
+This bug was manifesting itself during session shutdown within
+isert_cq_rx_comp_err() where target_wait_for_sess_cmds() would
+end up waiting indefinately for the last se_cmd->cmd_kref put to
+occur for the failed SCSI WRITE + ImmediateData descriptors.
+
+This fix follows what traditional iscsi-target code already does
+for the same failure case within iscsit_get_immediate_data().
+
+Reported-by: Sagi Grimberg <sagig@dev.mellanox.co.il>
+Cc: Sagi Grimberg <sagig@dev.mellanox.co.il>
+Cc: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/ulp/isert/ib_isert.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -1117,6 +1117,8 @@ sequence_cmd:
+       if (!rc && dump_payload == false && unsol_data)
+               iscsit_set_unsoliticed_dataout(cmd);
++      else if (dump_payload && imm_data)
++              target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
+       return 0;
+ }
diff --git a/queue-3.14/mm-add-pte_present-check-on-existing-hugetlb_entry-callbacks.patch b/queue-3.14/mm-add-pte_present-check-on-existing-hugetlb_entry-callbacks.patch
new file mode 100644 (file)
index 0000000..1b91816
--- /dev/null
@@ -0,0 +1,69 @@
+From d4c54919ed86302094c0ca7d48a8cbd4ee753e92 Mon Sep 17 00:00:00 2001
+From: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Date: Fri, 6 Jun 2014 10:00:01 -0400
+Subject: mm: add !pte_present() check on existing hugetlb_entry callbacks
+
+From: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+
+commit d4c54919ed86302094c0ca7d48a8cbd4ee753e92 upstream.
+
+The age table walker doesn't check non-present hugetlb entry in common
+path, so hugetlb_entry() callbacks must check it.  The reason for this
+behavior is that some callers want to handle it in its own way.
+
+[ I think that reason is bogus, btw - it should just do what the regular
+  code does, which is to call the "pte_hole()" function for such hugetlb
+  entries  - Linus]
+
+However, some callers don't check it now, which causes unpredictable
+result, for example when we have a race between migrating hugepage and
+reading /proc/pid/numa_maps.  This patch fixes it by adding !pte_present
+checks on buggy callbacks.
+
+This bug exists for years and got visible by introducing hugepage
+migration.
+
+ChangeLog v2:
+- fix if condition (check !pte_present() instead of pte_present())
+
+Reported-by: Sasha Levin <sasha.levin@oracle.com>
+Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ Backported to 3.15.  Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> ]
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/proc/task_mmu.c |    2 +-
+ mm/mempolicy.c     |    6 +++++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -1350,7 +1350,7 @@ static int gather_hugetbl_stats(pte_t *p
+       struct numa_maps *md;
+       struct page *page;
+-      if (pte_none(*pte))
++      if (!pte_present(*pte))
+               return 0;
+       page = pte_page(*pte);
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -526,9 +526,13 @@ static void queue_pages_hugetlb_pmd_rang
+       int nid;
+       struct page *page;
+       spinlock_t *ptl;
++      pte_t entry;
+       ptl = huge_pte_lock(hstate_vma(vma), vma->vm_mm, (pte_t *)pmd);
+-      page = pte_page(huge_ptep_get((pte_t *)pmd));
++      entry = huge_ptep_get((pte_t *)pmd);
++      if (!pte_present(entry))
++              goto unlock;
++      page = pte_page(entry);
+       nid = page_to_nid(page);
+       if (node_isset(nid, *nodes) == !!(flags & MPOL_MF_INVERT))
+               goto unlock;
diff --git a/queue-3.14/mm-rmap-fix-use-after-free-in-__put_anon_vma.patch b/queue-3.14/mm-rmap-fix-use-after-free-in-__put_anon_vma.patch
new file mode 100644 (file)
index 0000000..7cbf4c3
--- /dev/null
@@ -0,0 +1,42 @@
+From 624483f3ea82598ab0f62f1bdb9177f531ab1892 Mon Sep 17 00:00:00 2001
+From: Andrey Ryabinin <a.ryabinin@samsung.com>
+Date: Fri, 6 Jun 2014 19:09:30 +0400
+Subject: mm: rmap: fix use-after-free in __put_anon_vma
+
+From: Andrey Ryabinin <a.ryabinin@samsung.com>
+
+commit 624483f3ea82598ab0f62f1bdb9177f531ab1892 upstream.
+
+While working address sanitizer for kernel I've discovered
+use-after-free bug in __put_anon_vma.
+
+For the last anon_vma, anon_vma->root freed before child anon_vma.
+Later in anon_vma_free(anon_vma) we are referencing to already freed
+anon_vma->root to check rwsem.
+
+This fixes it by freeing the child anon_vma before freeing
+anon_vma->root.
+
+Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/rmap.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -1554,10 +1554,9 @@ void __put_anon_vma(struct anon_vma *ano
+ {
+       struct anon_vma *root = anon_vma->root;
++      anon_vma_free(anon_vma);
+       if (root != anon_vma && atomic_dec_and_test(&root->refcount))
+               anon_vma_free(root);
+-
+-      anon_vma_free(anon_vma);
+ }
+ static struct anon_vma *rmap_walk_anon_lock(struct page *page,
index 49ed1f6b1c5c171469892fe552b55fb163ab73a5..c35f3c83afdd63f1520f9ca2f03049f0a0ce2469 100644 (file)
@@ -65,3 +65,8 @@ intel_pstate-remove-c0-tracking.patch
 intel_pstate-correct-rounding-in-busy-calculation.patch
 intel_pstate-add-sample-time-scaling.patch
 intel_pstate-improve-initial-busy-calculation.patch
+mm-add-pte_present-check-on-existing-hugetlb_entry-callbacks.patch
+mm-rmap-fix-use-after-free-in-__put_anon_vma.patch
+iser-target-add-missing-target_put_sess_cmd-for-immedatedata-failure.patch
+iscsi-target-fix-wrong-buffer-buffer-overrun-in-iscsi_change_param_value.patch
+target-fix-alua_access_state-attribute-oops-for-un-configured-devices.patch
diff --git a/queue-3.14/target-fix-alua_access_state-attribute-oops-for-un-configured-devices.patch b/queue-3.14/target-fix-alua_access_state-attribute-oops-for-un-configured-devices.patch
new file mode 100644 (file)
index 0000000..a5297cc
--- /dev/null
@@ -0,0 +1,45 @@
+From f1453773514bb8b0bba0716301e8c8f17f8d39c7 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Fri, 6 Jun 2014 00:52:57 -0700
+Subject: target: Fix alua_access_state attribute OOPs for un-configured devices
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit f1453773514bb8b0bba0716301e8c8f17f8d39c7 upstream.
+
+This patch fixes a OOPs where an attempt to write to the per-device
+alua_access_state configfs attribute at:
+
+  /sys/kernel/config/target/core/$HBA/$DEV/alua/$TG_PT_GP/alua_access_state
+
+results in an NULL pointer dereference when the backend device has not
+yet been configured.
+
+This patch adds an explicit check for DF_CONFIGURED, and fails with
+-ENODEV to avoid this case.
+
+Reported-by: Chris Boot <crb@tiger-computing.co.uk>
+Reported-by: Philip Gaw <pgaw@darktech.org.uk>
+Cc: Chris Boot <crb@tiger-computing.co.uk>
+Cc: Philip Gaw <pgaw@darktech.org.uk>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_configfs.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/target/target_core_configfs.c
++++ b/drivers/target/target_core_configfs.c
+@@ -2223,6 +2223,11 @@ static ssize_t target_core_alua_tg_pt_gp
+                       " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id);
+               return -EINVAL;
+       }
++      if (!(dev->dev_flags & DF_CONFIGURED)) {
++              pr_err("Unable to set alua_access_state while device is"
++                     " not configured\n");
++              return -ENODEV;
++      }
+       ret = kstrtoul(page, 0, &tmp);
+       if (ret < 0) {