[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>
This commit is contained in:
parent
1fc8010a5d
commit
da3cc679b2
|
@ -1608,6 +1608,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
|
|||
int status;
|
||||
struct aac_dev *dev;
|
||||
struct fib * cmd_fibcontext;
|
||||
int cid;
|
||||
|
||||
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
|
||||
/*
|
||||
|
@ -1657,6 +1658,22 @@ static int aac_read(struct scsi_cmnd * scsicmd)
|
|||
count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
|
||||
break;
|
||||
}
|
||||
|
||||
if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
|
||||
cid = scmd_id(scsicmd);
|
||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||
min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
|
||||
SCSI_SENSE_BUFFERSIZE));
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",
|
||||
smp_processor_id(), (unsigned long long)lba, jiffies));
|
||||
if (aac_adapter_bounds(dev,scsicmd,lba))
|
||||
|
@ -1698,6 +1715,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
|||
int status;
|
||||
struct aac_dev *dev;
|
||||
struct fib * cmd_fibcontext;
|
||||
int cid;
|
||||
|
||||
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
|
||||
/*
|
||||
|
@ -1737,6 +1755,22 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
|||
count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
|
||||
fua = scsicmd->cmnd[1] & 0x8;
|
||||
}
|
||||
|
||||
if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
|
||||
cid = scmd_id(scsicmd);
|
||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||
min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
|
||||
SCSI_SENSE_BUFFERSIZE));
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
|
||||
smp_processor_id(), (unsigned long long)lba, jiffies));
|
||||
if (aac_adapter_bounds(dev,scsicmd,lba))
|
||||
|
|
Loading…
Reference in a new issue