]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
idiag: fix idiagnl_msg_clone()
authorThomas Haller <thaller@redhat.com>
Mon, 24 Nov 2014 16:14:54 +0000 (17:14 +0100)
committerThomas Haller <thaller@redhat.com>
Mon, 24 Nov 2014 17:36:52 +0000 (18:36 +0100)
For one, we did not clone all pointer values. Hence, every cloned
object was very broken and resulted in dangling pointers and
double free/unref.

Apparently nobody was really using this function up to now.

Also, fix the return cases for NLE_NOMEM, so that we did not assume
ownership of pointers in 'src'.

Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Thomas Haller <thaller@redhat.com>
lib/idiag/idiag_msg_obj.c

index 1d9fde8a769a52fbd3ed1639b469879d75ced52b..b212f69d0e8316f42e6b7bc07a4e82ba6ce3f79b 100644 (file)
@@ -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;
 }