diff options
author | Thomas Haller <thaller@redhat.com> | 2014-11-24 16:14:54 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-11-24 17:36:52 (GMT) |
commit | 39ca54ab4d9464e8951a0c67fe33ff1ce906e642 (patch) | |
tree | 8bf064214497cc2ae3558a686955a177653ad961 /lib/idiag | |
parent | f40fd71701e444d91a02c7f06ffbd4fcf232c9b9 (diff) | |
download | libnl-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.c | 27 |
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; } |