summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Egerer <thomas.egerer@secunet.com>2023-11-27 15:58:19 +0100
committerThomas Haller <thaller@redhat.com>2023-11-27 20:30:31 +0100
commitc4c22d267117900b9582d5c2e934c107419c9603 (patch)
treec3fe76ad18ff89a0431d68bd82016e4112065c10
parent5979fcb0a6855ddc8fa3b3a20d6ba37c1856d040 (diff)
downloadlibnl-c4c22d267117900b9582d5c2e934c107419c9603.tar.gz
xfrm/sp: fix reference counters of sa selector/tmpl addresses
It's a similar issue as in commit 3f4f1dda, when calling xfrmnl_sp_parse, the refcount of the addresses for selectors and templates increases to two, as xfrmnl_sel_set_[s|d]addr and xfrmnl_user_tmpl_set_[s|d]addr add another reference to the address object. As only one of those refs is dropped in sel_destroy or xfrmnl_user_tmpl_free respectively the address objects' refcount will never drop to zero, causing a leak. Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com> Fixes: 917154470895 ('xfrm: add xfrm support')
-rw-r--r--lib/xfrm/sp.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/lib/xfrm/sp.c b/lib/xfrm/sp.c
index cf106517..81c3a0f7 100644
--- a/lib/xfrm/sp.c
+++ b/lib/xfrm/sp.c
@@ -596,6 +596,8 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.daddr.a6, sizeof (sp_info->sel.daddr.a6));
nl_addr_set_prefixlen (addr, sp_info->sel.prefixlen_d);
xfrmnl_sel_set_daddr (sp->sel, addr);
+ /* Drop the reference count from the above set operation */
+ nl_addr_put(addr);
xfrmnl_sel_set_prefixlen_d (sp->sel, sp_info->sel.prefixlen_d);
if (sp_info->sel.family == AF_INET)
@@ -604,6 +606,8 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.saddr.a6, sizeof (sp_info->sel.saddr.a6));
nl_addr_set_prefixlen (addr, sp_info->sel.prefixlen_s);
xfrmnl_sel_set_saddr (sp->sel, addr);
+ /* Drop the reference count from the above set operation */
+ nl_addr_put(addr);
xfrmnl_sel_set_prefixlen_s (sp->sel, sp_info->sel.prefixlen_s);
xfrmnl_sel_set_dport (sp->sel, ntohs (sp_info->sel.dport));
@@ -680,6 +684,8 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
else
addr = nl_addr_build(tmpl->family, &tmpl->id.daddr.a6, sizeof (tmpl->id.daddr.a6));
xfrmnl_user_tmpl_set_daddr (sputmpl, addr);
+ /* Drop the reference count from the above set operation */
+ nl_addr_put(addr);
xfrmnl_user_tmpl_set_spi (sputmpl, ntohl(tmpl->id.spi));
xfrmnl_user_tmpl_set_proto (sputmpl, tmpl->id.proto);
xfrmnl_user_tmpl_set_family (sputmpl, tmpl->family);
@@ -689,6 +695,8 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
else
addr = nl_addr_build(tmpl->family, &tmpl->saddr.a6, sizeof (tmpl->saddr.a6));
xfrmnl_user_tmpl_set_saddr (sputmpl, addr);
+ /* Drop the reference count from the above set operation */
+ nl_addr_put(addr);
xfrmnl_user_tmpl_set_reqid (sputmpl, tmpl->reqid);
xfrmnl_user_tmpl_set_mode (sputmpl, tmpl->mode);