]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Aug 2012 18:33:19 +0000 (11:33 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Aug 2012 18:33:19 +0000 (11:33 -0700)
added patches:
target-add-range-checking-to-unmap-emulation.patch
target-check-number-of-unmap-descriptors-against-our-limit.patch
target-fix-possible-integer-underflow-in-unmap-emulation.patch
target-fix-reading-of-data-length-fields-for-unmap-commands.patch

queue-3.4/series
queue-3.4/target-add-range-checking-to-unmap-emulation.patch [new file with mode: 0644]
queue-3.4/target-check-number-of-unmap-descriptors-against-our-limit.patch [new file with mode: 0644]
queue-3.4/target-fix-possible-integer-underflow-in-unmap-emulation.patch [new file with mode: 0644]
queue-3.4/target-fix-reading-of-data-length-fields-for-unmap-commands.patch [new file with mode: 0644]

index a9ec21ac5374b907813b224ed32d5dfbedde8455..f06f80ae6f7b66879e6769495656ba46cd8b7396 100644 (file)
@@ -48,3 +48,7 @@ hid-add-asus-aio-keyboard-model-ak1d.patch
 x86-microcode-microcode_core.c-simple_strtoul-cleanup.patch
 x86-microcode-sanitize-per-cpu-microcode-reloading-interface.patch
 mm-hugetlbfs-close-race-during-teardown-of-hugetlbfs-shared-page-tables.patch
+target-add-range-checking-to-unmap-emulation.patch
+target-fix-reading-of-data-length-fields-for-unmap-commands.patch
+target-fix-possible-integer-underflow-in-unmap-emulation.patch
+target-check-number-of-unmap-descriptors-against-our-limit.patch
diff --git a/queue-3.4/target-add-range-checking-to-unmap-emulation.patch b/queue-3.4/target-add-range-checking-to-unmap-emulation.patch
new file mode 100644 (file)
index 0000000..2587041
--- /dev/null
@@ -0,0 +1,43 @@
+From: Roland Dreier <roland@purestorage.com>
+Date: Mon, 16 Jul 2012 15:34:22 -0700
+Subject: target: Add range checking to UNMAP emulation
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 2594e29865c291db162313187612cd9f14538f33 upstream.
+
+When processing an UNMAP command, we need to make sure that the number
+of blocks we're asked to UNMAP does not exceed our reported maximum
+number of blocks per UNMAP, and that the range of blocks we're
+unmapping doesn't go past the end of the device.
+
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+[bwh: Backported to 3.2: adjust filename, context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/target_core_cdb.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/target/target_core_cdb.c
++++ b/drivers/target/target_core_cdb.c
+@@ -1053,6 +1053,18 @@ int target_emulate_unmap(struct se_task
+               pr_debug("UNMAP: Using lba: %llu and range: %u\n",
+                                (unsigned long long)lba, range);
++              if (range > dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count) {
++                      cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
++                      ret = -EINVAL;
++                      goto err;
++              }
++
++              if (lba + range > dev->transport->get_blocks(dev) + 1) {
++                      cmd->scsi_sense_reason = TCM_ADDRESS_OUT_OF_RANGE;
++                      ret = -EINVAL;
++                      goto err;
++              }
++
+               ret = dev->transport->do_discard(dev, lba, range);
+               if (ret < 0) {
+                       pr_err("blkdev_issue_discard() failed: %d\n",
diff --git a/queue-3.4/target-check-number-of-unmap-descriptors-against-our-limit.patch b/queue-3.4/target-check-number-of-unmap-descriptors-against-our-limit.patch
new file mode 100644 (file)
index 0000000..d9a9884
--- /dev/null
@@ -0,0 +1,34 @@
+From: Roland Dreier <roland@purestorage.com>
+Date: Mon, 16 Jul 2012 15:34:25 -0700
+Subject: target: Check number of unmap descriptors against our limit
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 7409a6657aebf8be74c21d0eded80709b27275cb upstream.
+
+Fail UNMAP commands that have more than our reported limit on unmap
+descriptors.
+
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+[bwh: Backported to 3.2: adjust filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/target_core_cdb.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/target/target_core_cdb.c
++++ b/drivers/target/target_core_cdb.c
+@@ -1041,6 +1041,11 @@ int target_emulate_unmap(struct se_task
+       bd_dl = get_unaligned_be16(&buf[2]);
+       size = min(size - 8, bd_dl);
++      if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
++              cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
++              ret = -EINVAL;
++              goto err;
++      }
+       /* First UNMAP block descriptor starts at 8 byte offset */
+       ptr = &buf[8];
diff --git a/queue-3.4/target-fix-possible-integer-underflow-in-unmap-emulation.patch b/queue-3.4/target-fix-possible-integer-underflow-in-unmap-emulation.patch
new file mode 100644 (file)
index 0000000..25aa623
--- /dev/null
@@ -0,0 +1,71 @@
+From: Roland Dreier <roland@purestorage.com>
+Date: Mon, 16 Jul 2012 15:34:24 -0700
+Subject: target: Fix possible integer underflow in UNMAP emulation
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit b7fc7f3777582dea85156a821d78a522a0c083aa upstream.
+
+It's possible for an initiator to send us an UNMAP command with a
+descriptor that is less than 8 bytes; in that case it's really bad for
+us to set an unsigned int to that value, subtract 8 from it, and then
+use that as a limit for our loop (since the value will wrap around to
+a huge positive value).
+
+Fix this by making size be signed and only looping if size >= 16 (ie
+if we have at least a full descriptor available).
+
+Also remove offset as an obfuscated name for the constant 8.
+
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+[bwh: Backported to 3.2: adjust filename, context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/target_core_cdb.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/target/target_core_cdb.c
++++ b/drivers/target/target_core_cdb.c
+@@ -1023,9 +1023,10 @@ int target_emulate_unmap(struct se_task
+       struct se_device *dev = cmd->se_dev;
+       unsigned char *buf, *ptr = NULL;
+       sector_t lba;
+-      unsigned int size = cmd->data_length, range;
+-      int ret = 0, offset;
+-      unsigned short dl, bd_dl;
++      int size = cmd->data_length;
++      u32 range;
++      int ret = 0;
++      int dl, bd_dl;
+       if (!dev->transport->do_discard) {
+               pr_err("UNMAP emulation not supported for: %s\n",
+@@ -1034,20 +1035,19 @@ int target_emulate_unmap(struct se_task
+               return -ENOSYS;
+       }
+-      /* First UNMAP block descriptor starts at 8 byte offset */
+-      offset = 8;
+-      size -= 8;
+-
+       buf = transport_kmap_data_sg(cmd);
+       dl = get_unaligned_be16(&buf[0]);
+       bd_dl = get_unaligned_be16(&buf[2]);
+-      ptr = &buf[offset];
+-      pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
++      size = min(size - 8, bd_dl);
++
++      /* First UNMAP block descriptor starts at 8 byte offset */
++      ptr = &buf[8];
++      pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u"
+               " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);
+-      while (size) {
++      while (size >= 16) {
+               lba = get_unaligned_be64(&ptr[0]);
+               range = get_unaligned_be32(&ptr[8]);
+               pr_debug("UNMAP: Using lba: %llu and range: %u\n",
diff --git a/queue-3.4/target-fix-reading-of-data-length-fields-for-unmap-commands.patch b/queue-3.4/target-fix-reading-of-data-length-fields-for-unmap-commands.patch
new file mode 100644 (file)
index 0000000..f6f4efd
--- /dev/null
@@ -0,0 +1,47 @@
+From: Roland Dreier <roland@purestorage.com>
+Date: Mon, 16 Jul 2012 15:34:23 -0700
+Subject: target: Fix reading of data length fields for UNMAP commands
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 1a5fa4576ec8a462313c7516b31d7453481ddbe8 upstream.
+
+The UNMAP DATA LENGTH and UNMAP BLOCK DESCRIPTOR DATA LENGTH fields
+are in the unmap descriptor (the payload transferred to our data out
+buffer), not in the CDB itself.  Read them from the correct place in
+target_emulated_unmap.
+
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+[bwh: Backported to 3.2: adjust filename, context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/target_core_cdb.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/target/target_core_cdb.c
++++ b/drivers/target/target_core_cdb.c
+@@ -1022,7 +1022,6 @@ int target_emulate_unmap(struct se_task
+       struct se_cmd *cmd = task->task_se_cmd;
+       struct se_device *dev = cmd->se_dev;
+       unsigned char *buf, *ptr = NULL;
+-      unsigned char *cdb = &cmd->t_task_cdb[0];
+       sector_t lba;
+       unsigned int size = cmd->data_length, range;
+       int ret = 0, offset;
+@@ -1038,11 +1037,12 @@ int target_emulate_unmap(struct se_task
+       /* First UNMAP block descriptor starts at 8 byte offset */
+       offset = 8;
+       size -= 8;
+-      dl = get_unaligned_be16(&cdb[0]);
+-      bd_dl = get_unaligned_be16(&cdb[2]);
+       buf = transport_kmap_data_sg(cmd);
++      dl = get_unaligned_be16(&buf[0]);
++      bd_dl = get_unaligned_be16(&buf[2]);
++
+       ptr = &buf[offset];
+       pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
+               " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);