[PATCH 10/13] idiag: fix idiagnl_msg_clone()

Thomas Haller thaller at redhat.com
Mon Nov 24 08:14:54 PST 2014


For one, we did not clone all pointer value. Hence, every cloned
object would result in a double free/unref.

Also, in case of NLE_NOMEM, we would also free the fields
owned by src.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/idiag/idiag_msg_obj.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/lib/idiag/idiag_msg_obj.c b/lib/idiag/idiag_msg_obj.c
index 1d9fde8..b212f69 100644
--- a/lib/idiag/idiag_msg_obj.c
+++ b/lib/idiag/idiag_msg_obj.c
@@ -572,13 +572,36 @@ static int idiagnl_msg_clone(struct nl_object *_dst, struct nl_object *_src)
 	struct idiagnl_msg *dst = (struct idiagnl_msg *) _dst;
 	struct idiagnl_msg *src = (struct idiagnl_msg *) _src;
 
-	if (src->idiag_src)
+	dst->idiag_cong = NULL;
+	dst->idiag_src = NULL;
+	dst->idiag_dst = NULL;
+	dst->idiag_meminfo = NULL;
+	dst->idiag_vegasinfo = NULL;
+
+	if (src->idiag_cong) {
+		if (!(dst->idiag_cong = strdup(src->idiag_cong)))
+			return -NLE_NOMEM;
+	}
+
+	if (src->idiag_src) {
 		if (!(dst->idiag_src = nl_addr_clone(src->idiag_src)))
 			return -NLE_NOMEM;
+	}
 
-	if (src->idiag_dst)
+	if (src->idiag_dst) {
 		if (!(dst->idiag_dst = nl_addr_clone(src->idiag_dst)))
 			return -NLE_NOMEM;
+	}
+
+	if (src->idiag_meminfo) {
+		if (!(dst->idiag_meminfo = (struct idiagnl_meminfo *) nl_object_clone((struct nl_object *) src->idiag_meminfo)))
+			return -NLE_NOMEM;
+	}
+
+	if (src->idiag_vegasinfo) {
+		if (!(dst->idiag_vegasinfo = (struct idiagnl_vegasinfo *) nl_object_clone((struct nl_object *) src->idiag_vegasinfo)))
+			return -NLE_NOMEM;
+	}
 
 	return 0;
 }
-- 
1.9.3




More information about the libnl mailing list