summaryrefslogtreecommitdiffstats
path: root/lib/idiag
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-11-24 16:14:54 (GMT)
committerThomas Haller <thaller@redhat.com>2014-11-24 17:36:52 (GMT)
commit39ca54ab4d9464e8951a0c67fe33ff1ce906e642 (patch)
tree8bf064214497cc2ae3558a686955a177653ad961 /lib/idiag
parentf40fd71701e444d91a02c7f06ffbd4fcf232c9b9 (diff)
downloadlibnl-39ca54ab4d9464e8951a0c67fe33ff1ce906e642.zip
libnl-39ca54ab4d9464e8951a0c67fe33ff1ce906e642.tar.gz
libnl-39ca54ab4d9464e8951a0c67fe33ff1ce906e642.tar.bz2
idiag: fix idiagnl_msg_clone()
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>
Diffstat (limited to 'lib/idiag')
-rw-r--r--lib/idiag/idiag_msg_obj.c27
1 files 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;
}