Commit 95a3639e authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

[SCSI] fix bugs in scsi_vpd_inquiry()

Universally, SCSI functions assume the lengths fed in are those of the buffer
to DMA data to, not the lengths of the data minus the header.
scsi_vpd_inquiry() assumed the latter and got it wrong, so fix up all the
functions to use the correct assumption (and fix a bug where INQUIRY in SCSI-2
dcannot go over 255).


[jejb: Matthew posted an identical version of this at the same time I did]
Signed-off-by: default avatarMatthew Wilcox <matthew@wil.cx>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 5f91bb05
...@@ -994,7 +994,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, ...@@ -994,7 +994,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
* all the existing users tried this hard. * all the existing users tried this hard.
*/ */
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
len + 4, NULL, 30 * HZ, 3, NULL); len, NULL, 30 * HZ, 3, NULL);
if (result) if (result)
return result; return result;
...@@ -1021,13 +1021,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page) ...@@ -1021,13 +1021,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
{ {
int i, result; int i, result;
unsigned int len; unsigned int len;
unsigned char *buf = kmalloc(259, GFP_KERNEL); const unsigned int init_vpd_len = 255;
unsigned char *buf = kmalloc(init_vpd_len, GFP_KERNEL);
if (!buf) if (!buf)
return NULL; return NULL;
/* Ask for all the pages supported by this device */ /* Ask for all the pages supported by this device */
result = scsi_vpd_inquiry(sdev, buf, 0, 255); result = scsi_vpd_inquiry(sdev, buf, 0, init_vpd_len);
if (result) if (result)
goto fail; goto fail;
...@@ -1050,12 +1051,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page) ...@@ -1050,12 +1051,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
* Some pages are longer than 255 bytes. The actual length of * Some pages are longer than 255 bytes. The actual length of
* the page is returned in the header. * the page is returned in the header.
*/ */
len = (buf[2] << 8) | buf[3]; len = ((buf[2] << 8) | buf[3]) + 4;
if (len <= 255) if (len <= init_vpd_len)
return buf; return buf;
kfree(buf); kfree(buf);
buf = kmalloc(len + 4, GFP_KERNEL); buf = kmalloc(len, GFP_KERNEL);
result = scsi_vpd_inquiry(sdev, buf, page, len); result = scsi_vpd_inquiry(sdev, buf, page, len);
if (result) if (result)
goto fail; goto fail;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment