Skip to content

Commit db111e1

Browse files
Stephen M. CameronJames Bottomley
authored andcommitted
[SCSI] hpsa: fix potential overrun while memcpy'ing sense data
This memcpy: memcpy(cmd->sense_buffer, ei->SenseInfo, ei->SenseLen > SCSI_SENSE_BUFFERSIZE ? SCSI_SENSE_BUFFERSIZE : ei->SenseLen); The ei->SenseLen field is filled in by the Smart Array. For requests to logical drives, it will not exceed 32 bytes, so should be ok, but for physical requests it depends on the target device, not the Smart Array. It's conceivable that this could exceed the 32 byte size of ei->SenseInfo. In that case, the memcpy would read past the end of ei->SenseInfo, copying data from the next command, as if it were sense data, or, if it happened to be the very last command in the block of allocated commands, could fall off the end of the allocated area and crash. I'm not aware of anyone ever encountering this behavior, but it could conceivably happen. This bug was found by Coverity. Signed-off-by: Stephen M. Cameron <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent c2dd32e commit db111e1

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

drivers/scsi/hpsa.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ static void complete_scsi_command(struct CommandList *cp)
10371037
unsigned char sense_key;
10381038
unsigned char asc; /* additional sense code */
10391039
unsigned char ascq; /* additional sense code qualifier */
1040+
unsigned long sense_data_size;
10401041

10411042
ei = cp->err_info;
10421043
cmd = (struct scsi_cmnd *) cp->scsi_cmd;
@@ -1051,10 +1052,14 @@ static void complete_scsi_command(struct CommandList *cp)
10511052
cmd->result |= ei->ScsiStatus;
10521053

10531054
/* copy the sense data whether we need to or not. */
1054-
memcpy(cmd->sense_buffer, ei->SenseInfo,
1055-
ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
1056-
SCSI_SENSE_BUFFERSIZE :
1057-
ei->SenseLen);
1055+
if (SCSI_SENSE_BUFFERSIZE < sizeof(ei->SenseInfo))
1056+
sense_data_size = SCSI_SENSE_BUFFERSIZE;
1057+
else
1058+
sense_data_size = sizeof(ei->SenseInfo);
1059+
if (ei->SenseLen < sense_data_size)
1060+
sense_data_size = ei->SenseLen;
1061+
1062+
memcpy(cmd->sense_buffer, ei->SenseInfo, sense_data_size);
10581063
scsi_set_resid(cmd, ei->ResidualCnt);
10591064

10601065
if (ei->CommandStatus == 0) {

0 commit comments

Comments
 (0)