[stgt] [PATCH 03/13] spc: fix data-in buffer generation for INQUIRY cmd
nezhinsky at gmail.com
nezhinsky at gmail.com
Wed Jan 16 10:01:43 CET 2013
From: Alexander Nezhinsky <nezhinsky at gmail.com>
Generate inquiry data-in in a separate buffer and safe-copy it to the command
buffer taking into account the allocation length.
Signed-off-by: Alexander Nezhinsky <nezhinsky at gmail.com>
---
usr/spc.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/usr/spc.c b/usr/spc.c
index e850d21..d3c5857 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -194,9 +194,10 @@ static void update_b0_opt_xfer_len(struct scsi_lu *lu, int opt_xfer_len)
int spc_inquiry(int host_no, struct scsi_cmd *cmd)
{
- int len = 0, ret = SAM_STAT_CHECK_CONDITION;
+ int ret = SAM_STAT_CHECK_CONDITION;
uint8_t *data;
uint8_t *scb = cmd->scb;
+ uint32_t alloc_len, avail_len, actual_len;
unsigned char key = ILLEGAL_REQUEST;
uint16_t asc = ASC_INVALID_FIELD_IN_CDB;
uint8_t devtype = 0;
@@ -207,11 +208,13 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
if (!(scb[1] & 0x1) && scb[2])
goto sense;
- if (scsi_get_in_length(cmd) < scb[4])
+ alloc_len = (uint32_t)get_unaligned_be16(&scb[3]);
+ if (scsi_get_in_length(cmd) < alloc_len)
goto sense;
memset(buf, 0, sizeof(buf));
data = buf;
+ avail_len = 0;
dprintf("%x %x\n", scb[1], scb[2]);
@@ -239,8 +242,8 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
for (i = 0; i < ARRAY_SIZE(attrs->version_desc); i++)
*desc++ = __cpu_to_be16(attrs->version_desc[i]);
- len = 66;
- data[4] = len - 5; /* Additional Length */
+ avail_len = 66;
+ data[4] = avail_len - 5; /* Additional Length */
ret = SAM_STAT_GOOD;
} else if (scb[1] & 0x1) {
uint8_t pcode = scb[2];
@@ -263,7 +266,7 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
}
data[3] = cnt;
data[4] = 0x0;
- len = cnt + 4;
+ avail_len = cnt + 4;
ret = SAM_STAT_GOOD;
} else if (attrs->lu_vpd[PCODE_OFFSET(pcode)]) {
vpd_pg = attrs->lu_vpd[PCODE_OFFSET(pcode)];
@@ -273,7 +276,7 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
data[2] = (vpd_pg->size >> 8);
data[3] = vpd_pg->size & 0xff;
memcpy(&data[4], vpd_pg->data, vpd_pg->size);
- len = vpd_pg->size + 4;
+ avail_len = vpd_pg->size + 4;
ret = SAM_STAT_GOOD;
}
}
@@ -284,8 +287,9 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
if (cmd->dev->lun != cmd->dev_id)
data[0] = TYPE_NO_LUN;
- scsi_set_in_resid_by_actual(cmd, len);
- memcpy(scsi_get_in_buffer(cmd), data, scb[4]);
+ actual_len = mem_copy_n32(scsi_get_in_buffer(cmd), data, avail_len,
+ NULL, &alloc_len);
+ scsi_set_in_resid_by_actual(cmd, actual_len);
return SAM_STAT_GOOD;
sense:
--
1.7.9.6
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list