From 395f3baed6df1eb736c872ecaa3aa2f05c5dc111 Mon Sep 17 00:00:00 2001
From: lishengyu <lishengyu@uniontech.com>
Date: Thu, 23 Jun 2022 14:02:49 +0800
Subject: [PATCH] lsns: fix the memory leak.

==28129== 96 bytes in 3 blocks are possibly lost in loss record 1 of 4
==28129==    at 0x4837B65: calloc (vg_replace_malloc.c:752)
==28129==    by 0x405C83: xcalloc (xalloc.h:60)
==28129==    by 0x405C83: netnsid_cache_add (lsns.c:389)
==28129==    by 0x405C83: get_netnsid (lsns.c:486)
==28129==    by 0x405C83: read_process (lsns.c:549)
==28129==    by 0x403FB4: read_processes (lsns.c:586)
==28129==    by 0x403FB4: main (lsns.c:1417)
==28129==
==28129== 119,664 (384 direct, 119,280 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4
==28129==    at 0x4837B65: calloc (vg_replace_malloc.c:752)
==28129==    by 0x4055F5: xcalloc (xalloc.h:60)
==28129==    by 0x4055F5: read_process (lsns.c:516)
==28129==    by 0x403FB4: read_processes (lsns.c:586)
==28129==    by 0x403FB4: main (lsns.c:1417)
---
 include/list.h   | 19 +++++++++++++++++++
 sys-utils/lsns.c | 25 +++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/include/list.h b/include/list.h
index 96c84e5..b6bbbdd 100644
--- a/include/list.h
+++ b/include/list.h
@@ -208,6 +208,25 @@ _INLINE_ void list_splice(struct list_head *list, struct list_head *head)
 	for (pos = (head)->next, pnext = pos->next; pos != (head); \
 	     pos = pnext, pnext = pos->next)
 
+/**
+ * list_free - remove all entries from list and call freefunc()
+ *             for each entry
+ * @head:       the head for your list
+ * @type:       the type of the struct this is embedded in.
+ * @member:     the name of the list_struct within the struct.
+ * @freefunc:   the list entry deallocator
+ */
+#define list_free(head, type, member, freefunc)				\
+	do {								\
+		struct list_head *__p, *__pnext;			\
+									\
+		list_for_each_safe (__p, __pnext, (head)) {		\
+			type *__elt = list_entry(__p, type, member);	\
+			list_del(__p);					\
+			freefunc(__elt);			\
+		}							\
+	} while (0)
+
 _INLINE_ size_t list_count_entries(struct list_head *head)
 {
 	struct list_head *pos;
diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c
index 8e25ff1..baa80bd 100644
--- a/sys-utils/lsns.c
+++ b/sys-utils/lsns.c
@@ -953,6 +953,28 @@ static int show_namespace_processes(struct lsns *ls, struct lsns_namespace *ns)
 	return 0;
 }
 
+static void free_lsns_process(struct lsns_process *lsns_p)
+{
+	free(lsns_p);
+}
+
+static void free_netnsid_caches(struct netnsid_cache *cache)
+{
+	free(cache);
+}
+
+static void free_lsns_namespace(struct lsns_namespace *lsns_n)
+{
+	free(lsns_n);
+}
+
+static void free_all(struct lsns *ls)
+{
+	list_free(&ls->processes, struct lsns_process, processes, free_lsns_process);
+	list_free(&netnsids_cache, struct netnsid_cache, netnsids, free_netnsid_caches);
+	list_free(&ls->namespaces, struct lsns_namespace, namespaces, free_lsns_namespace);
+}
+
 static void __attribute__((__noreturn__)) usage(void)
 {
 	FILE *out = stdout;
@@ -1162,5 +1184,8 @@ int main(int argc, char *argv[])
 	if (netlink_fd >= 0)
 		close(netlink_fd);
 	free_idcache(uid_cache);
+	
+	free_all(&ls);
+
 	return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
-- 
2.27.0

