summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Dreier <roland@purestorage.com>2012-07-16 15:34:22 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-15 07:53:02 -0700
commitdb72573b925c8258376aecaf7df99debfae11384 (patch)
treef100273dc86fe6ea8cd8818019c8945d86a85860
parenta29d332e9ac886c15af3911b43fba26bfc45ed9e (diff)
target: Add range checking to UNMAP emulation
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>
-rw-r--r--drivers/target/target_core_cdb.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index 664f6e775d0e..0a12d46dc517 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -1044,6 +1044,18 @@ int target_emulate_unmap(struct se_cmd *cmd)
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",