Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 4287

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: Tomas Henzl <thenzl@redhat.com>
Date: Tue, 17 Aug 2010 15:03:22 -0400
Subject: [scsi] fix bugs in scsi_vpd_inquiry
Message-id: <20100817150322.6769.33564.sendpatchset@localhost.localdomain>
Patchwork-id: 27660
O-Subject: [RHEL5.6 PATCH2/5] scsi: fix bugs in scsi_vpd_inquiry()
Bugzilla: 599420
RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>

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).

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=95a3639e275fb7aec5c9a2116c88a2cdd23e0b8b
Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index de47479..3a7a9fe 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -835,7 +835,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3);
+				  len, NULL, 30 * HZ, 3);
 	if (result)
 		return result;
 
@@ -862,13 +862,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 {
 	int i, result;
 	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)
 		return NULL;
 
 	/* 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)
 		goto fail;
 
@@ -891,12 +892,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 	 * Some pages are longer than 255 bytes.  The actual length of
 	 * the page is returned in the header.
 	 */
-	len = (buf[2] << 8) | buf[3];
-	if (len <= 255)
+	len = ((buf[2] << 8) | buf[3]) + 4;
+	if (len <= init_vpd_len)
 		return buf;
 
 	kfree(buf);
-	buf = kmalloc(len + 4, GFP_KERNEL);
+	buf = kmalloc(len, GFP_KERNEL);
 	result = scsi_vpd_inquiry(sdev, buf, page, len);
 	if (result)
 		goto fail;