aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajashekhara, Mahesh <Mahesh_Rajashekhara@adaptec.com>2010-05-10 07:24:01 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-16 22:49:46 -0400
commitda3cc679b247a22efe0746d129074015b278e64d (patch)
tree4949e9cabd0e3a7df4c840d3185af3a4a7a45849
parent1fc8010a5d9a27391db2be103b13f4ac80990cfc (diff)
[SCSI] aacraid: prohibit access to array container space
Problem description: -------------------- The issue reported by one of the customer was able to read LBA beyond the array reported size with "sg_read" utility. If N is the last block address reported, then should not be able to read past N, i.e. N+1. But in their case, reported last LBA=143134719. So should not have been able to read with LBA=143134720, but it is read without failure, which means reported size to the OS is not correct and is less than the actual last block address. Solution: --------- Firmware layer exposes lesser container capacity than the actual one. It exposes [Actual size - Spitfire space(10MB)] to the OS, IO's to the 10MB should be prohibited from the Linux driver. Driver checks LBA boundary, if its greater than the array reported size then sets sensekey to HARDWARE_ERROR and sends the notification to the MID layer. Signed-off-by: Mahesh Rajashekhara <aacraid@adaptec.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/aacraid/aachba.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index fdc7d9935aeb..7df2dd1d2c6f 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1608,6 +1608,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
1608 int status; 1608 int status;
1609 struct aac_dev *dev; 1609 struct aac_dev *dev;
1610 struct fib * cmd_fibcontext; 1610 struct fib * cmd_fibcontext;
1611 int cid;
1611 1612
1612 dev = (struct aac_dev *)scsicmd->device->host->hostdata; 1613 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
1613 /* 1614 /*
@@ -1657,6 +1658,22 @@ static int aac_read(struct scsi_cmnd * scsicmd)
1657 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; 1658 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
1658 break; 1659 break;
1659 } 1660 }
1661
1662 if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
1663 cid = scmd_id(scsicmd);
1664 dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
1665 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
1666 SAM_STAT_CHECK_CONDITION;
1667 set_sense(&dev->fsa_dev[cid].sense_data,
1668 HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
1669 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
1670 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
1671 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
1672 SCSI_SENSE_BUFFERSIZE));
1673 scsicmd->scsi_done(scsicmd);
1674 return 1;
1675 }
1676
1660 dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", 1677 dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",
1661 smp_processor_id(), (unsigned long long)lba, jiffies)); 1678 smp_processor_id(), (unsigned long long)lba, jiffies));
1662 if (aac_adapter_bounds(dev,scsicmd,lba)) 1679 if (aac_adapter_bounds(dev,scsicmd,lba))
@@ -1698,6 +1715,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
1698 int status; 1715 int status;
1699 struct aac_dev *dev; 1716 struct aac_dev *dev;
1700 struct fib * cmd_fibcontext; 1717 struct fib * cmd_fibcontext;
1718 int cid;
1701 1719
1702 dev = (struct aac_dev *)scsicmd->device->host->hostdata; 1720 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
1703 /* 1721 /*
@@ -1737,6 +1755,22 @@ static int aac_write(struct scsi_cmnd * scsicmd)
1737 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; 1755 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
1738 fua = scsicmd->cmnd[1] & 0x8; 1756 fua = scsicmd->cmnd[1] & 0x8;
1739 } 1757 }
1758
1759 if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
1760 cid = scmd_id(scsicmd);
1761 dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
1762 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
1763 SAM_STAT_CHECK_CONDITION;
1764 set_sense(&dev->fsa_dev[cid].sense_data,
1765 HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
1766 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
1767 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
1768 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
1769 SCSI_SENSE_BUFFERSIZE));
1770 scsicmd->scsi_done(scsicmd);
1771 return 1;
1772 }
1773
1740 dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", 1774 dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
1741 smp_processor_id(), (unsigned long long)lba, jiffies)); 1775 smp_processor_id(), (unsigned long long)lba, jiffies));
1742 if (aac_adapter_bounds(dev,scsicmd,lba)) 1776 if (aac_adapter_bounds(dev,scsicmd,lba))