[PATCH 1/1] SBC READ: return correct key/ascq when reading beyond end-of-lun

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



List, Tomo

Please find attached a patch to TGTD that verifies SCSI READ* for 1 or
more blocks do not pass beyond the end of the device.
If too long read is encoutnered, return the correct sense with
key:illegal request   and ascq:lba out of range


regards
ronnie sahlberg

Attachment: 0001-SBC-READ-When-reading-1-or-more-blocks-of-data-verif.patch.gz
Description: GNU Zip compressed data

From 3dd66c502c341ced04609c8826df7dc4934bac06 Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
Date: Mon, 4 Apr 2011 17:43:47 +1000
Subject: [PATCH] SBC READ: When reading 1 or more blocks of data, verify that we are not
 reading past the end of the lun and if so return the correct sense

key: illegal request
ascq: lba out of range

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
---
 usr/sbc.c |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/usr/sbc.c b/usr/sbc.c
index 5603495..f7b1e17 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -102,6 +102,8 @@ static int sbc_mode_sense(int host_no, struct scsi_cmd *cmd)
 static int sbc_rw(int host_no, struct scsi_cmd *cmd)
 {
 	int ret;
+	uint64_t lba;
+	uint32_t tl;
 	unsigned char key = ILLEGAL_REQUEST;
 	uint16_t asc = ASC_LUN_NOT_SUPPORTED;
 	struct scsi_lu *lu = cmd->dev;
@@ -123,9 +125,27 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
 		}
 	}
 
+	lba = scsi_rw_offset(cmd->scb) << cmd->dev->blk_shift;
+	tl  = scsi_rw_count(cmd->scb) << cmd->dev->blk_shift;
+
+	/* Verify that if we are reading data that we are not reading beyond
+	   the end-of-lun */
+	switch (cmd->scb[0]) {
+	case READ_6:
+	case READ_10:
+	case READ_12:
+	case READ_16:
+		if (tl && (lba + tl > lu->size)) {
+			key = ILLEGAL_REQUEST;
+			asc = ASC_LBA_OUT_OF_RANGE;
+			goto sense;
+		}
+		break;
+	}
+
 	cmd->scsi_cmd_done = target_cmd_io_done;
+	cmd->offset = lba;
 
-	cmd->offset = (scsi_rw_offset(cmd->scb) << cmd->dev->blk_shift);
 	ret = cmd->dev->bst->bs_cmd_submit(cmd);
 	if (ret) {
 		key = HARDWARE_ERROR;
-- 
1.7.3.1


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux