link: fix memory leaks due to repeated calls to .io_alloc()
All the io_alloc() implementation unconditionally allocated new memory, thus leaking memory if called more then once. Fix io_alloc() implementations not to allocate new memory if not needed. This happens for example in link_msg_parser() which first calls rtnl_link_set_type(): #0 macvlan_alloc (link=0x609d50) at route/link/macvlan.c:56 #1 0x00007ffff7b99a78 in rtnl_link_set_type (link=link@entry=0x609d50, type=type@entry=0x609a94 "macvlan") at route/link.c:2233 #2 0x00007ffff7b99c28 in link_msg_parser (ops=<optimized out>, who=<optimized out>, n=<optimized out>, pp=0x7fffffffd870) at route/link.c:547 #3 0x00007ffff7dea109 in nl_cache_parse (ops=0x7ffff7dd8600 <rtnl_link_ops>, who=0x603338, nlh=0x6098a0, params=0x7fffffffd870) at cache.c:914 #4 0x00007ffff7dea15b in update_msg_parser (msg=<optimized out>, arg=<optimized out>) at cache.c:668 #5 0x00007ffff7def7bf in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:142 #6 recvmsgs (cb=0x6057a0, sk=0x6034c0) at nl.c:952 #7 nl_recvmsgs_report (sk=sk@entry=0x6034c0, cb=cb@entry=0x6057a0) at nl.c:1003 #8 0x00007ffff7defb79 in nl_recvmsgs (sk=sk@entry=0x6034c0, cb=cb@entry=0x6057a0) at nl.c:1027 #9 0x00007ffff7de9668 in __cache_pickup (sk=0x6034c0, cache=0x603510, param=param@entry=0x7fffffffd870) at cache.c:701 #10 0x00007ffff7dea08d in nl_cache_pickup (sk=<optimized out>, cache=<optimized out>) at cache.c:753 #11 0x0000000000400d56 in main () and later ops->io_parse(): #0 macvlan_alloc (link=0x609d50) at route/link/macvlan.c:56 #1 0x00007ffff7baae9d in macvlan_parse (link=0x609d50, data=<optimized out>, xstats=<optimized out>) at route/link/macvlan.c:79 #2 0x00007ffff7b99c80 in link_msg_parser (ops=<optimized out>, who=<optimized out>, n=<optimized out>, pp=0x7fffffffd870) at route/link.c:567 #3 0x00007ffff7dea109 in nl_cache_parse (ops=0x7ffff7dd8600 <rtnl_link_ops>, who=0x603338, nlh=0x6098a0, params=0x7fffffffd870) at cache.c:914 #4 0x00007ffff7dea15b in update_msg_parser (msg=<optimized out>, arg=<optimized out>) at cache.c:668 #5 0x00007ffff7def7bf in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:142 #6 recvmsgs (cb=0x6057a0, sk=0x6034c0) at nl.c:952 #7 nl_recvmsgs_report (sk=sk@entry=0x6034c0, cb=cb@entry=0x6057a0) at nl.c:1003 #8 0x00007ffff7defb79 in nl_recvmsgs (sk=sk@entry=0x6034c0, cb=cb@entry=0x6057a0) at nl.c:1027 #9 0x00007ffff7de9668 in __cache_pickup (sk=0x6034c0, cache=0x603510, param=param@entry=0x7fffffffd870) at cache.c:701 #10 0x00007ffff7dea08d in nl_cache_pickup (sk=<optimized out>, cache=<optimized out>) at cache.c:753 #11 0x0000000000400d56 in main () https://github.com/thom311/libnl/issues/59 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
parent
b0d0d339cd
commit
d65c32a720
9 changed files with 71 additions and 33 deletions
|
@ -73,11 +73,15 @@ static int can_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct can_info *ci;
|
||||
|
||||
ci = calloc(1, sizeof(*ci));
|
||||
if (!ci)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*ci));
|
||||
else {
|
||||
ci = calloc(1, sizeof(*ci));
|
||||
if (!ci)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = ci;
|
||||
link->l_info = ci;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -73,11 +73,15 @@ static int ip6_tnl_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct ip6_tnl_info *ip6_tnl;
|
||||
|
||||
ip6_tnl = calloc(1, sizeof(*ip6_tnl));
|
||||
if (!ip6_tnl)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*ip6_tnl));
|
||||
else {
|
||||
ip6_tnl = calloc(1, sizeof(*ip6_tnl));
|
||||
if (!ip6_tnl)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = ip6_tnl;
|
||||
link->l_info = ip6_tnl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -75,11 +75,15 @@ static int ipgre_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct ipgre_info *ipgre;
|
||||
|
||||
ipgre = calloc(1, sizeof(*ipgre));
|
||||
if (!ipgre)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*ipgre));
|
||||
else {
|
||||
ipgre = calloc(1, sizeof(*ipgre));
|
||||
if (!ipgre)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = ipgre;
|
||||
link->l_info = ipgre;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -62,11 +62,15 @@ static int ipip_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct ipip_info *ipip;
|
||||
|
||||
ipip = calloc(1, sizeof(*ipip));
|
||||
if (!ipip)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*ipip));
|
||||
else {
|
||||
ipip = calloc(1, sizeof(*ipip));
|
||||
if (!ipip)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = ipip;
|
||||
link->l_info = ipip;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -59,11 +59,15 @@ static int ipvti_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct ipvti_info *ipvti;
|
||||
|
||||
ipvti = calloc(1, sizeof(*ipvti));
|
||||
if (!ipvti)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*ipvti));
|
||||
else {
|
||||
ipvti = calloc(1, sizeof(*ipvti));
|
||||
if (!ipvti)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = ipvti;
|
||||
link->l_info = ipvti;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -55,10 +55,14 @@ static int macvlan_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct macvlan_info *mvi;
|
||||
|
||||
if ((mvi = calloc(1, sizeof(*mvi))) == NULL)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*mvi));
|
||||
else {
|
||||
if ((mvi = calloc(1, sizeof(*mvi))) == NULL)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = mvi;
|
||||
link->l_info = mvi;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -69,11 +69,15 @@ static int sit_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct sit_info *sit;
|
||||
|
||||
sit = calloc(1, sizeof(*sit));
|
||||
if (!sit)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*sit));
|
||||
else {
|
||||
sit = calloc(1, sizeof(*sit));
|
||||
if (!sit)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = sit;
|
||||
link->l_info = sit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -67,10 +67,16 @@ static int vlan_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct vlan_info *vi;
|
||||
|
||||
if ((vi = calloc(1, sizeof(*vi))) == NULL)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info) {
|
||||
vi = link->l_info;
|
||||
free(vi->vi_egress_qos);
|
||||
memset(link->l_info, 0, sizeof(*vi));
|
||||
} else {
|
||||
if ((vi = calloc(1, sizeof(*vi))) == NULL)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = vi;
|
||||
link->l_info = vi;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -91,10 +91,14 @@ static int vxlan_alloc(struct rtnl_link *link)
|
|||
{
|
||||
struct vxlan_info *vxi;
|
||||
|
||||
if ((vxi = calloc(1, sizeof(*vxi))) == NULL)
|
||||
return -NLE_NOMEM;
|
||||
if (link->l_info)
|
||||
memset(link->l_info, 0, sizeof(*vxi));
|
||||
else {
|
||||
if ((vxi = calloc(1, sizeof(*vxi))) == NULL)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
link->l_info = vxi;
|
||||
link->l_info = vxi;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue