summaryrefslogtreecommitdiffstats
path: root/lib/xfrm/sa.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-03-15 10:35:02 (GMT)
committerThomas Haller <thaller@redhat.com>2022-03-16 23:11:14 (GMT)
commitd23fb814998f7afd26e2eb678919b0e3a796a91f (patch)
tree28f95d689f2cf70d5aa3923a0fa99100532123b8 /lib/xfrm/sa.c
parent7f7452c973a4f55f4d8ab6f8b36493a3b00a9397 (diff)
downloadlibnl-d23fb814998f7afd26e2eb678919b0e3a796a91f.zip
libnl-d23fb814998f7afd26e2eb678919b0e3a796a91f.tar.gz
libnl-d23fb814998f7afd26e2eb678919b0e3a796a91f.tar.bz2
lib: make nl_object_clone() out-of-memory safe
nl_object_clone() first does a shallow copy using memcpy(). That is useful, because it can correctly copy simple fields (like numbers). For pointer values, we need to implement oo_clone() to fixup the pointers and get the deep-copy correct. Now, oo_clone() must always follow through, to un-alias the copied pointer. In particular also in the error case. The oo_clone() implementations sometimes fail (with ENOMEM) and just return. In those cases, we must make sure that we don't leave the wrong pointers there. The pointers must be cleared first. Otherwise, any failure (which basically are ENOMEM) leave the object in an inconsistent state, and we double-free/use-after-free the pointers.
Diffstat (limited to 'lib/xfrm/sa.c')
-rw-r--r--lib/xfrm/sa.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c
index d453c26..3b657bf 100644
--- a/lib/xfrm/sa.c
+++ b/lib/xfrm/sa.c
@@ -136,6 +136,20 @@ static int xfrm_sa_clone(struct nl_object *_dst, struct nl_object *_src)
struct xfrmnl_sa* src = nl_object_priv(_src);
uint32_t len = 0;
+ dst->sel = NULL;
+ dst->id.daddr = NULL;
+ dst->saddr = NULL;
+ dst->lft = NULL;
+ dst->aead = NULL;
+ dst->auth = NULL;
+ dst->crypt = NULL;
+ dst->comp = NULL;
+ dst->encap = NULL;
+ dst->coaddr = NULL;
+ dst->sec_ctx = NULL;
+ dst->replay_state_esn = NULL;
+ dst->user_offload = NULL;
+
if (src->sel)
if ((dst->sel = xfrmnl_sel_clone (src->sel)) == NULL)
return -NLE_NOMEM;