lib: Fix a memory leak in scsi_cdb_persistent_reserve_out()
If scsi_cdb_persistent_reserve_out() succeeds a call to scsi_free_scsi_task() won't free any memory allocated with scsi_malloc() in this function because the memset() call in this function overwrites the task->mem pointer. Move the memset() call up such that it doesn't clear task->mem. This makes it possible for the caller of this function to free the memory allocated by this function by calling scsi_free_scsi_task(). Merge the error handling code such that the code for freeing memory only occurs once. Signed-off-by: Bart Van Assche <bvanassche@acm.org>
This commit is contained in:
committed by
Ronnie Sahlberg
parent
afa076b537
commit
3fdc3f2327
@@ -2037,15 +2037,14 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|||||||
int xferlen;
|
int xferlen;
|
||||||
|
|
||||||
task = malloc(sizeof(struct scsi_task));
|
task = malloc(sizeof(struct scsi_task));
|
||||||
if (task == NULL) {
|
if (task == NULL)
|
||||||
return NULL;
|
goto err;
|
||||||
}
|
|
||||||
|
memset(task, 0, sizeof(struct scsi_task));
|
||||||
|
|
||||||
iov = scsi_malloc(task, sizeof(struct scsi_iovec));
|
iov = scsi_malloc(task, sizeof(struct scsi_iovec));
|
||||||
if (iov == NULL) {
|
if (iov == NULL)
|
||||||
free(task);
|
goto err;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(sa) {
|
switch(sa) {
|
||||||
case SCSI_PERSISTENT_RESERVE_REGISTER:
|
case SCSI_PERSISTENT_RESERVE_REGISTER:
|
||||||
@@ -2059,11 +2058,8 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|||||||
|
|
||||||
xferlen = 24;
|
xferlen = 24;
|
||||||
buf = scsi_malloc(task, xferlen);
|
buf = scsi_malloc(task, xferlen);
|
||||||
if (buf == NULL) {
|
if (buf == NULL)
|
||||||
free(task);
|
goto err;
|
||||||
free(iov);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buf, 0, xferlen);
|
memset(buf, 0, xferlen);
|
||||||
scsi_set_uint64(&buf[0], basic->reservation_key);
|
scsi_set_uint64(&buf[0], basic->reservation_key);
|
||||||
@@ -2080,19 +2076,12 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|||||||
break;
|
break;
|
||||||
case SCSI_PERSISTENT_RESERVE_REGISTER_AND_MOVE:
|
case SCSI_PERSISTENT_RESERVE_REGISTER_AND_MOVE:
|
||||||
/* XXX FIXME */
|
/* XXX FIXME */
|
||||||
free(task);
|
goto err;
|
||||||
free(iov);
|
|
||||||
return NULL;
|
|
||||||
default:
|
default:
|
||||||
free(task);
|
goto err;
|
||||||
free(iov);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task->cdb[0] = SCSI_OPCODE_PERSISTENT_RESERVE_OUT;
|
||||||
memset(task, 0, sizeof(struct scsi_task));
|
|
||||||
task->cdb[0] = SCSI_OPCODE_PERSISTENT_RESERVE_OUT;
|
|
||||||
|
|
||||||
task->cdb[1] |= sa & 0x1f;
|
task->cdb[1] |= sa & 0x1f;
|
||||||
task->cdb[2] = ((scope << 4) & 0xf0) | (type & 0x0f);
|
task->cdb[2] = ((scope << 4) & 0xf0) | (type & 0x0f);
|
||||||
|
|
||||||
@@ -2107,6 +2096,10 @@ scsi_cdb_persistent_reserve_out(enum scsi_persistent_out_sa sa, enum scsi_persis
|
|||||||
scsi_task_set_iov_out(task, iov, 1);
|
scsi_task_set_iov_out(task, iov, 1);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
|
|
||||||
|
err:
|
||||||
|
scsi_free_scsi_task(task);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user