CP-18038: Fix multiple resource leaks

In 'vhd_util_coalesce_load_chain()', cleaning up in case of an
error is wrongly implemented.

Basically, we try to figure out if the object pointed to by 'entry'
has made its way into the list or not. Although the rationale for
doing that is not wrong per se (checking if its list was empty,
which it technically is, until it is added to one), it needed
something extra to work; its 'list_head' member initialized by calling
'INIT_LIST_HEAD(&entry->next)'. This had to be done for every newly
allocated object.

The approach we took here is a bit different. Instead of doing the
above, which would have worked fine but is not semantically accurate,
we check if 'entry->next.next' is 'NULL' or not. If it is, it means
it has not been added to any list and we should explicitly free it.
Otherwise, 'vhd_util_coalesce_free_chain()' will free it.

Also, ensure that 'entry->raw_fd' is not negative before calling
'close()' on it.

Signed-off-by: Kostas Ladopoulos <konstantinos.ladopoulos@citrix.com>
Reviewed-by: Germano Percossi <germano.percossi@citrix.com>

diff --git a/vhd/lib/vhd-util-coalesce.c b/vhd/lib/vhd-util-coalesce.c
index d45ea83..c170706 100644
--- a/vhd/lib/vhd-util-coalesce.c
+++ b/vhd/lib/vhd-util-coalesce.c
@@ -402,10 +402,16 @@ done:
 	err = 0;
 out:
 	if (err) {
-		if (entry && list_empty(&entry->next)) {
+		/*
+		 * If 'entry->next.next' is NULL, it means 'entry'
+		 * is not part of list 'head'; hence, it won't be
+		 * freed by 'vhd_util_coalesce_free_chain()'
+		 * and needs to be freed explicitly.
+		 */
+		if (entry && !entry->next.next) {
 			if (entry->vhd.file)
 				vhd_close(&entry->vhd);
-			else if (entry->raw)
+			else if (entry->raw && (entry->raw_fd >= 0))
 				close(entry->raw_fd);
 			free(entry);
 		}
