[PATCH] aacraid: READ_CAPACITY_16 shouldn't trust allocation length in cdb

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

 



When aacraid spoofs READ_CAPACITY_16, it assumes that the data length
in the sg list is equal to allocation length in cdb. But sg can put
any value in scb so the driver needs to check both the data length in
the sg list and allocation length in cdb.

If allocation length is larger than the response length that the
driver expects, it clears the data buffer in the sg list to zero but
it doesn't need to do. Just setting resid is fine.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx>
Cc: Mark Salyzyn <Mark_Salyzyn@xxxxxxxxxxx>
Cc: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx>
---
 drivers/scsi/aacraid/aachba.c |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index c05092f..b9fc9b1 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -2047,6 +2047,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 	{
 		u64 capacity;
 		char cp[13];
+		unsigned int alloc_len;
 
 		dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
 		capacity = fsa_dev_ptr[cid].size - 1;
@@ -2063,18 +2064,17 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		cp[10] = 2;
 		cp[11] = 0;
 		cp[12] = 0;
-		aac_internal_transfer(scsicmd, cp, 0,
-		  min_t(size_t, scsicmd->cmnd[13], sizeof(cp)));
-		if (sizeof(cp) < scsicmd->cmnd[13]) {
-			unsigned int len, offset = sizeof(cp);
 
-			memset(cp, 0, offset);
-			do {
-				len = min_t(size_t, scsicmd->cmnd[13] - offset,
-						sizeof(cp));
-				aac_internal_transfer(scsicmd, cp, offset, len);
-			} while ((offset += len) < scsicmd->cmnd[13]);
-		}
+		alloc_len = ((scsicmd->cmnd[10] << 24)
+			     + (scsicmd->cmnd[11] << 16)
+			     + (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]);
+
+		alloc_len = min_t(size_t, alloc_len, sizeof(cp));
+		aac_internal_transfer(scsicmd, cp, 0, alloc_len);
+
+		if (alloc_len < scsi_bufflen(scsicmd))
+			scsi_set_resid(scsicmd,
+				       scsi_bufflen(scsicmd) - alloc_len);
 
 		/* Do not cache partition table for arrays */
 		scsicmd->device->removable = 1;
-- 
1.5.3.7

-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux