[Stgt-devel] [PATCH 2/2] plug valloc leaks

Pete Wyckoff pw
Sat Oct 27 20:34:53 CEST 2007


A few inquiry and related handlers do not release their valloc-ed pages
in error paths.  Fix these.

ibmvio inquiry:  only alloc when needed for __ibmvio_inquiry, not for
spc_inquiry.

smc read element status:  inspect reserved byte first, free for
unknown element type.

spc inquiry:  free in error path.

spc mode sense:  free in sense for a few failure cases.

Signed-off-by: Pete Wyckoff <pw at osc.edu>
---
 usr/ibmvio/ibmvio.c |   10 +++++-----
 usr/smc.c           |    7 ++++---
 usr/spc.c           |    8 ++++++--
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/usr/ibmvio/ibmvio.c b/usr/ibmvio/ibmvio.c
index 5836498..0e6b256 100644
--- a/usr/ibmvio/ibmvio.c
+++ b/usr/ibmvio/ibmvio.c
@@ -146,6 +146,11 @@ static int ibmvio_inquiry(int host_no, struct scsi_cmd *cmd)
 	if (((scb[1] & 0x3) == 0x3) || (!(scb[1] & 0x3) && scb[2]))
 		goto sense;
 
+	dprintf("%x %x\n", scb[1], scb[2]);
+
+	if (scb[1] & 0x3)
+		return spc_inquiry(host_no, cmd);
+
 	data = valloc(pagesize);
 	if (!data) {
 		key = HARDWARE_ERROR;
@@ -154,11 +159,6 @@ static int ibmvio_inquiry(int host_no, struct scsi_cmd *cmd)
 	}
 	memset(data, 0, pagesize);
 
-	dprintf("%x %x\n", scb[1], scb[2]);
-
-	if (scb[1] & 0x3)
-		return spc_inquiry(host_no, cmd);
-
 	cmd->len = __ibmvio_inquiry(host_no, cmd, data);
 	cmd->len = min_t(int, cmd->len, scb[4]);
 	cmd->uaddr = (unsigned long) data;
diff --git a/usr/smc.c b/usr/smc.c
index df38b25..9d55992 100644
--- a/usr/smc.c
+++ b/usr/smc.c
@@ -273,6 +273,9 @@ static int smc_read_element_status(int host_no, struct scsi_cmd *cmd)
 		goto sense;
 	}
 
+	if (scb[11])	/* Reserved byte */
+		goto sense;
+
 	data = valloc(pagesize);
 	if (!data) {
 		dprintf("valloc(%lu) failed\n", pagesize);
@@ -282,9 +285,6 @@ static int smc_read_element_status(int host_no, struct scsi_cmd *cmd)
 	}
 	memset(data, 0, pagesize);
 
-	if (scb[11])	/* Reserved byte */
-		goto sense;
-
 	switch(element_type) {
 	case ELEMENT_ANY:
 		/* Return element in type order */
@@ -333,6 +333,7 @@ static int smc_read_element_status(int host_no, struct scsi_cmd *cmd)
 						  dvcid, voltag);
 		break;
 	default:
+		free(data);
 		goto sense;
 		break;
 	}
diff --git a/usr/spc.c b/usr/spc.c
index 45a0430..3e1f65e 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -234,8 +234,10 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
 		}
 	}
 
-	if (ret != SAM_STAT_GOOD)
+	if (ret != SAM_STAT_GOOD) {
+		free(data);
 		goto sense;
+	}
 
 	cmd->len = min_t(int, len, scb[4]);
 	cmd->uaddr = (unsigned long) data;
@@ -373,7 +375,7 @@ static int build_mode_page(uint8_t *data, struct mode_pg *pg)
 int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
 {
 	int len = 0;
-	uint8_t *data, *scb, mode6, dbd, pcode, subpcode;
+	uint8_t *data = NULL, *scb, mode6, dbd, pcode, subpcode;
 	uint16_t alloc_len;
 	unsigned char key = ILLEGAL_REQUEST;
 	uint16_t asc = ASC_INVALID_FIELD_IN_CDB;
@@ -441,6 +443,8 @@ int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 
 sense:
+	if (data)
+		free(data);
 	cmd->len = 0;
 	sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
-- 
1.5.3.4




More information about the stgt mailing list