|
|
dc245c |
lib: Fix a memory leak in scsi_cdb_persistent_reserve_out()
|
|
|
dc245c |
|
|
|
dc245c |
Message-id: <1383729402-27559-5-git-send-email-pbonzini@redhat.com>
|
|
|
dc245c |
Patchwork-id: 55499
|
|
|
dc245c |
O-Subject: [PATCH 04/11] lib: Fix a memory leak in scsi_cdb_persistent_reserve_out()
|
|
|
dc245c |
Bugzilla: 1026820
|
|
|
dc245c |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
dc245c |
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
|
|
|
dc245c |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
dc245c |
|
|
|
dc245c |
From: Bart Van Assche <bvanassche@acm.org>
|
|
|
dc245c |
|
|
|
dc245c |
If scsi_cdb_persistent_reserve_out() succeeds a call to
|
|
|
dc245c |
scsi_free_scsi_task() won't free any memory allocated with scsi_malloc()
|
|
|
dc245c |
in this function because the memset() call in this function overwrites
|
|
|
dc245c |
the task->mem pointer. Move the memset() call up such that it doesn't
|
|
|
dc245c |
clear task->mem. This makes it possible for the caller of this function
|
|
|
dc245c |
to free the memory allocated by this function by calling
|
|
|
dc245c |
scsi_free_scsi_task(). Merge the error handling code such that the code
|
|
|
dc245c |
for freeing memory only occurs once.
|
|
|
dc245c |
|
|
|
dc245c |
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
|
|
|
dc245c |
(cherry picked from commit 3fdc3f2327939174b1691eca6a55915cc3e08b8b)
|
|
|
dc245c |
---
|
|
|
dc245c |
The problem reported by Coverity is that scsi_malloc accesses
|
|
|
dc245c |
task->mem, which is uninitialized.
|
|
|
dc245c |
|
|
|
dc245c |
lib/scsi-lowlevel.c | 37 +++++++++++++++----------------------
|
|
|
dc245c |
1 file changed, 15 insertions(+), 22 deletions(-)
|
|
|
dc245c |
diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c
|
|
|
dc245c |
index 0f97a79..28d0a08 100644
|
|
|
dc245c |
--- a/lib/scsi-lowlevel.c
|
|
|
dc245c |
+++ b/lib/scsi-lowlevel.c
|
|
|
dc245c |
@@ -1874,15 +1874,14 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|
|
dc245c |
int xferlen;
|
|
|
dc245c |
|
|
|
dc245c |
task = malloc(sizeof(struct scsi_task));
|
|
|
dc245c |
- if (task == NULL) {
|
|
|
dc245c |
- return NULL;
|
|
|
dc245c |
- }
|
|
|
dc245c |
+ if (task == NULL)
|
|
|
dc245c |
+ goto err;
|
|
|
dc245c |
+
|
|
|
dc245c |
+ memset(task, 0, sizeof(struct scsi_task));
|
|
|
dc245c |
|
|
|
dc245c |
iov = scsi_malloc(task, sizeof(struct scsi_iovec));
|
|
|
dc245c |
- if (iov == NULL) {
|
|
|
dc245c |
- free(task);
|
|
|
dc245c |
- return NULL;
|
|
|
dc245c |
- }
|
|
|
dc245c |
+ if (iov == NULL)
|
|
|
dc245c |
+ goto err;
|
|
|
dc245c |
|
|
|
dc245c |
switch(sa) {
|
|
|
dc245c |
case SCSI_PERSISTENT_RESERVE_REGISTER:
|
|
|
dc245c |
@@ -1896,11 +1895,8 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|
|
dc245c |
|
|
|
dc245c |
xferlen = 24;
|
|
|
dc245c |
buf = scsi_malloc(task, xferlen);
|
|
|
dc245c |
- if (buf == NULL) {
|
|
|
dc245c |
- free(task);
|
|
|
dc245c |
- free(iov);
|
|
|
dc245c |
- return NULL;
|
|
|
dc245c |
- }
|
|
|
dc245c |
+ if (buf == NULL)
|
|
|
dc245c |
+ goto err;
|
|
|
dc245c |
|
|
|
dc245c |
memset(buf, 0, xferlen);
|
|
|
dc245c |
scsi_set_uint64(&buf[0], basic->reservation_key);
|
|
|
dc245c |
@@ -1917,19 +1913,12 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|
|
dc245c |
break;
|
|
|
dc245c |
case SCSI_PERSISTENT_RESERVE_REGISTER_AND_MOVE:
|
|
|
dc245c |
/* XXX FIXME */
|
|
|
dc245c |
- free(task);
|
|
|
dc245c |
- free(iov);
|
|
|
dc245c |
- return NULL;
|
|
|
dc245c |
+ goto err;
|
|
|
dc245c |
default:
|
|
|
dc245c |
- free(task);
|
|
|
dc245c |
- free(iov);
|
|
|
dc245c |
- return NULL;
|
|
|
dc245c |
+ goto err;
|
|
|
dc245c |
}
|
|
|
dc245c |
|
|
|
dc245c |
-
|
|
|
dc245c |
- memset(task, 0, sizeof(struct scsi_task));
|
|
|
dc245c |
- task->cdb[0] = SCSI_OPCODE_PERSISTENT_RESERVE_OUT;
|
|
|
dc245c |
-
|
|
|
dc245c |
+ task->cdb[0] = SCSI_OPCODE_PERSISTENT_RESERVE_OUT;
|
|
|
dc245c |
task->cdb[1] |= sa & 0x1f;
|
|
|
dc245c |
task->cdb[2] = ((scope << 4) & 0xf0) | (type & 0x0f);
|
|
|
dc245c |
|
|
|
dc245c |
@@ -1944,6 +1933,10 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|
|
dc245c |
scsi_task_set_iov_out(task, iov, 1);
|
|
|
dc245c |
|
|
|
dc245c |
return task;
|
|
|
dc245c |
+
|
|
|
dc245c |
+err:
|
|
|
dc245c |
+ scsi_free_scsi_task(task);
|
|
|
dc245c |
+ return NULL;
|
|
|
dc245c |
}
|
|
|
dc245c |
|
|
|
dc245c |
/*
|