diff options
author | Hans Dedecker <dedeckeh@gmail.com> | 2018-04-01 12:21:38 +0200 |
---|---|---|
committer | Hans Dedecker <dedeckeh@gmail.com> | 2018-04-02 10:43:52 +0200 |
commit | 3dc8c916a94483bba2eed5ba34ccfc864866bb4e (patch) | |
tree | 6b843a5fd85103ed57ffa6b7f89a7de0eb5d958c | |
parent | 9c8d7816fc5e966b0c0efab9c1234734e0c5c254 (diff) |
interface-ip: fix memory leak in interface_ip_add_target_route()
Commit 9c8d781 introduced a memory leak in interface_ip_add_target_route
in case interface_ip_find_addr_target returns true for a given address
by not freeing the previously allocated route.
While at it rework the logic so a host route is only allocated when it's
really required.
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r-- | interface-ip.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/interface-ip.c b/interface-ip.c index 1c84d4f..6726a69 100644 --- a/interface-ip.c +++ b/interface-ip.c @@ -229,18 +229,12 @@ interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *if { struct device_route *route, *r_next = NULL; bool defaultroute_target = false; + union if_addr addr_zero; int addrsize = v6 ? sizeof(addr->in6) : sizeof(addr->in); - route = calloc(1, sizeof(*route)); - if (!route) - return NULL; - - route->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4; - route->mask = v6 ? 128 : 32; - if (memcmp(&route->addr, addr, addrsize) == 0) + memset(&addr_zero, 0, sizeof(addr_zero)); + if (memcmp(&addr_zero, addr, addrsize) == 0) defaultroute_target = true; - else - memcpy(&route->addr, addr, addrsize); if (iface) { /* look for locally addressable target first */ @@ -262,21 +256,27 @@ interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *if } } - if (!r_next) { - free(route); + if (!r_next) return NULL; - } iface = r_next->iface; + if (defaultroute_target) + return iface; + + route = calloc(1, sizeof(*route)); + if (!route) + return NULL; + + route->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4; + route->mask = v6 ? 128 : 32; + memcpy(&route->addr, addr, addrsize); memcpy(&route->nexthop, &r_next->nexthop, sizeof(route->nexthop)); route->mtu = r_next->mtu; route->metric = r_next->metric; route->table = r_next->table; route->iface = iface; - if (defaultroute_target) - free(route); - else - vlist_add(&iface->host_routes, &route->node, route); + vlist_add(&iface->host_routes, &route->node, route); + return iface; } |