All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
To: linux-modules <linux-modules@vger.kernel.org>
Cc: Lucas De Marchi <lucas.de.marchi@gmail.com>
Subject: [PATCH] depmod: fix errorpath memleaks in report cycles logic
Date: Mon, 20 Mar 2017 12:09:51 +0200	[thread overview]
Message-ID: <20170320100951.20884-1-yauheni.kaliuta@redhat.com> (raw)

From: Yauheni Kaliuta <y.kaliuta@gmail.com>

The c7ce9f0c80f3d561078a78205a14c5ba7663cfdd commit (depmod:
handle nested loops) introduced a bunch of possible memory leaks
in error path. In the real world scenario it is not a problem,
since the utility quits if it detects any of the errors, but from
the programming point of view, it is not nice. So, add the
cleanups.

Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
---
 tools/depmod.c | 54 +++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/tools/depmod.c b/tools/depmod.c
index 116adbeb14a0..7f9e9804787e 100644
--- a/tools/depmod.c
+++ b/tools/depmod.c
@@ -1481,10 +1481,10 @@ static void depmod_list_remove_data(struct kmod_list **list, void *data)
 	*list = l;
 }
 
-static void depmod_report_one_cycle(struct depmod *depmod,
-				    struct vertex *vertex,
-				    struct kmod_list **roots,
-				    struct hash *loop_set)
+static int depmod_report_one_cycle(struct depmod *depmod,
+				   struct vertex *vertex,
+				   struct kmod_list **roots,
+				   struct hash *loop_set)
 {
 	const char sep[] = " -> ";
 	size_t sz;
@@ -1493,6 +1493,7 @@ static void depmod_report_one_cycle(struct depmod *depmod,
 	int i;
 	int n;
 	struct vertex *v;
+	int rc;
 
 	array_init(&reverse, 3);
 
@@ -1503,7 +1504,10 @@ static void depmod_report_one_cycle(struct depmod *depmod,
 
 		sz += v->mod->modnamesz - 1;
 		array_append(&reverse, v);
-		hash_add(loop_set, v->mod->modname, NULL);
+		rc = hash_add(loop_set, v->mod->modname, NULL);
+		if (rc != 0)
+			return rc;
+		/* the hash will be freed where created */
 	}
 	sz += vertex->mod->modnamesz - 1;
 
@@ -1528,6 +1532,8 @@ static void depmod_report_one_cycle(struct depmod *depmod,
 
 	free(buf);
 	array_free_array(&reverse);
+
+	return 0;
 }
 
 static int depmod_report_cycles_from_root(struct depmod *depmod,
@@ -1545,17 +1551,18 @@ static int depmod_report_cycles_from_root(struct depmod *depmod,
 	struct mod *m;
 	struct mod **itr, **itr_end;
 	size_t is;
+	int ret = -ENOMEM;
 
 	root = vertex_new(root_mod, NULL);
 	if (root == NULL) {
 		ERR("No memory to report cycles\n");
-		return -ENOMEM;
+		goto out;
 	}
 
 	l = kmod_list_append(free_list, root);
 	if (l == NULL) {
 		ERR("No memory to report cycles\n");
-		return -ENOMEM;
+		goto out;
 	}
 	free_list = l;
 
@@ -1570,8 +1577,13 @@ static int depmod_report_cycles_from_root(struct depmod *depmod,
 		 * from part of a loop or from a branch after a loop
 		 */
 		if (m->visited && m == root->mod) {
-			depmod_report_one_cycle(depmod, vertex,
-						roots, loop_set);
+			int rc;
+			rc = depmod_report_one_cycle(depmod, vertex,
+						     roots, loop_set);
+			if (rc != 0) {
+				ret = rc;
+				goto out;
+			}
 			continue;
 		}
 
@@ -1598,7 +1610,7 @@ static int depmod_report_cycles_from_root(struct depmod *depmod,
 			v = vertex_new(dep, vertex);
 			if (v == NULL) {
 				ERR("No memory to report cycles\n");
-				return -ENOMEM;
+				goto out;
 			}
 			assert(is < stack_size);
 			stack[is++] = v;
@@ -1606,12 +1618,15 @@ static int depmod_report_cycles_from_root(struct depmod *depmod,
 			l = kmod_list_append(free_list, v);
 			if (l == NULL) {
 				ERR("No memory to report cycles\n");
-				return -ENOMEM;
+				goto out;
 			}
 			free_list = l;
 
 		}
 	}
+	ret = 0;
+
+out:
 	while (free_list) {
 		v = free_list->data;
 		l = kmod_list_remove(free_list);
@@ -1619,7 +1634,7 @@ static int depmod_report_cycles_from_root(struct depmod *depmod,
 		free(v);
 	}
 
-	return 0;
+	return ret;
 }
 
 static void depmod_report_cycles(struct depmod *depmod, uint16_t n_mods,
@@ -1643,7 +1658,7 @@ static void depmod_report_cycles(struct depmod *depmod, uint16_t n_mods,
 		l = kmod_list_append(roots, m);
 		if (l == NULL) {
 			ERR("No memory to report cycles\n");
-			return;
+			goto out_list;
 		}
 		roots = l;
 		n_r++;
@@ -1652,13 +1667,13 @@ static void depmod_report_cycles(struct depmod *depmod, uint16_t n_mods,
 	stack = malloc(n_r * sizeof(void *));
 	if (stack == NULL) {
 		ERR("No memory to report cycles\n");
-		return;
+		goto out_list;
 	}
 
 	loop_set = hash_new(16, NULL);
 	if (loop_set == NULL) {
 		ERR("No memory to report cycles\n");
-		return;
+		goto out_list;
 	}
 
 	while (roots != NULL) {
@@ -1670,14 +1685,19 @@ static void depmod_report_cycles(struct depmod *depmod, uint16_t n_mods,
 						     &roots,
 						     stack, n_r, loop_set);
 		if (err < 0)
-			goto err;
+			goto out_hash;
 	}
 
 	num_cyclic = hash_get_count(loop_set);
 	ERR("Found %d modules in dependency cycles!\n", num_cyclic);
 
-err:
+out_hash:
 	hash_free(loop_set);
+out_list:
+	while (roots != NULL) {
+		/* no need to free data, come from outside */
+		roots = kmod_list_remove(roots);
+	}
 }
 
 static int depmod_calculate_dependencies(struct depmod *depmod)
-- 
2.9.2.368.g08bb350

             reply	other threads:[~2017-03-20 10:09 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-20 10:09 Yauheni Kaliuta [this message]
2017-03-20 10:28 ` [PATCH] depmod: fix errorpath memleaks in report cycles logic Yauheni Kaliuta
2017-05-09  6:48   ` Lucas De Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170320100951.20884-1-yauheni.kaliuta@redhat.com \
    --to=yauheni.kaliuta@redhat.com \
    --cc=linux-modules@vger.kernel.org \
    --cc=lucas.de.marchi@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.