diff options
author | Thomas Egerer <thomas.egerer@secunet.com> | 2023-11-27 15:58:19 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-11-27 20:30:31 +0100 |
commit | c4c22d267117900b9582d5c2e934c107419c9603 (patch) | |
tree | c3fe76ad18ff89a0431d68bd82016e4112065c10 | |
parent | 5979fcb0a6855ddc8fa3b3a20d6ba37c1856d040 (diff) | |
download | libnl-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.c | 8 |
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); |