jtag/drivers/ulink: fix clang static analyzer warnings

scan-build-9:
Description: Potential leak of memory pointed to by 'cmd'
File: /home/vanekt/openocd/scanbuild9/../src/jtag/drivers/ulink.c
Line: 1075

Description: Potential leak of memory pointed to by 'cmd'
File: /home/vanekt/openocd/scanbuild9/../src/jtag/drivers/ulink.c
Line: 1275

ulink_append_xxx_cmd() functions allocate memory for cmd
and then call ulink_allocate_payload(), which allocates cmd->payload_out
or cmd->payload_in.

ulink_append_queue() checks the size of queue and if the new payload
does not fit, calls ulink_execute_queued_commands() and then
ulink_post_process_queue(). If any of these two fails, an error is
returned, allocated cmd struct leaks and the queue is left in an undefined
state.

Change ulink_append_queue() flow to proceed to appending cmd to the queue
even in the case of fail in previous ulink_execute_queued_commands()
or ulink_post_process_queue(). In case of fail then clear the queue
including the last appended cmd.

Change-Id: I967c07af19e9020c93bcb4ef403cf1f557dd1db1
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/5370
Tested-by: jenkins
Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
This commit is contained in:
Tomas Vanek 2020-03-13 15:34:47 +01:00 committed by Oleksij Rempel
parent 6dcd255b7b
commit 3c296bd194
1 changed files with 9 additions and 8 deletions

View File

@ -650,7 +650,7 @@ void ulink_clear_queue(struct ulink *device)
int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd)
{
int newsize_out, newsize_in;
int ret;
int ret = ERROR_OK;
newsize_out = ulink_get_queue_size(device, PAYLOAD_DIRECTION_OUT) + 1
+ ulink_cmd->payload_out_size;
@ -663,14 +663,12 @@ int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd)
/* New command does not fit. Execute all commands in queue before starting
* new queue with the current command as first entry. */
ret = ulink_execute_queued_commands(device, USB_TIMEOUT);
if (ret != ERROR_OK)
return ret;
ret = ulink_post_process_queue(device);
if (ret != ERROR_OK)
return ret;
if (ret == ERROR_OK)
ret = ulink_post_process_queue(device);
ulink_clear_queue(device);
if (ret == ERROR_OK)
ulink_clear_queue(device);
}
if (device->queue_start == NULL) {
@ -687,7 +685,10 @@ int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd)
device->queue_end = ulink_cmd;
}
return ERROR_OK;
if (ret != ERROR_OK)
ulink_clear_queue(device);
return ret;
}
/**