aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2009-08-11 11:59:09 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-08-22 18:52:23 -0400
commit95a3639e275fb7aec5c9a2116c88a2cdd23e0b8b (patch)
tree115b3d4fecf7e9089000c9f4bf5558be99670bf0 /drivers/scsi/scsi.c
parent5f91bb050ecc4ff1d8d3d07edbe550c8f431c5e1 (diff)
[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: Matthew Wilcox <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2de5f3ad640b..b6e03074cb8f 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -994,7 +994,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
994 * all the existing users tried this hard. 994 * all the existing users tried this hard.
995 */ 995 */
996 result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, 996 result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
997 len + 4, NULL, 30 * HZ, 3, NULL); 997 len, NULL, 30 * HZ, 3, NULL);
998 if (result) 998 if (result)
999 return result; 999 return result;
1000 1000
@@ -1021,13 +1021,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
1021{ 1021{
1022 int i, result; 1022 int i, result;
1023 unsigned int len; 1023 unsigned int len;
1024 unsigned char *buf = kmalloc(259, GFP_KERNEL); 1024 const unsigned int init_vpd_len = 255;
1025 unsigned char *buf = kmalloc(init_vpd_len, GFP_KERNEL);
1025 1026
1026 if (!buf) 1027 if (!buf)
1027 return NULL; 1028 return NULL;
1028 1029
1029 /* Ask for all the pages supported by this device */ 1030 /* Ask for all the pages supported by this device */
1030 result = scsi_vpd_inquiry(sdev, buf, 0, 255); 1031 result = scsi_vpd_inquiry(sdev, buf, 0, init_vpd_len);
1031 if (result) 1032 if (result)
1032 goto fail; 1033 goto fail;
1033 1034
@@ -1050,12 +1051,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
1050 * Some pages are longer than 255 bytes. The actual length of 1051 * Some pages are longer than 255 bytes. The actual length of
1051 * the page is returned in the header. 1052 * the page is returned in the header.
1052 */ 1053 */
1053 len = (buf[2] << 8) | buf[3]; 1054 len = ((buf[2] << 8) | buf[3]) + 4;
1054 if (len <= 255) 1055 if (len <= init_vpd_len)
1055 return buf; 1056 return buf;
1056 1057
1057 kfree(buf); 1058 kfree(buf);
1058 buf = kmalloc(len + 4, GFP_KERNEL); 1059 buf = kmalloc(len, GFP_KERNEL);
1059 result = scsi_vpd_inquiry(sdev, buf, page, len); 1060 result = scsi_vpd_inquiry(sdev, buf, page, len);
1060 if (result) 1061 if (result)
1061 goto fail; 1062 goto fail;