ACK Sincerely -- Mark Salyzyn > -----Original Message----- > From: fujita [mailto:tomof@xxxxxxx] On Behalf Of FUJITA Tomonori > Sent: Sunday, February 24, 2008 6:25 PM > To: linux-scsi@xxxxxxxxxxxxxxx > Cc: tomof@xxxxxxx; FUJITA Tomonori; Salyzyn, Mark; James Bottomley > Subject: [PATCH] aacraid: READ_CAPACITY_16 shouldn't trust > allocation length in cdb > > 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