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
--- /dev/null
+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",
--- /dev/null
+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];
--- /dev/null
+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",
--- /dev/null
+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);