summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2018-04-01 12:21:38 +0200
committerHans Dedecker <dedeckeh@gmail.com>2018-04-02 10:43:52 +0200
commit3dc8c916a94483bba2eed5ba34ccfc864866bb4e (patch)
tree6b843a5fd85103ed57ffa6b7f89a7de0eb5d958c
parent9c8d7816fc5e966b0c0efab9c1234734e0c5c254 (diff)
downloadnetifd-3dc8c916a94483bba2eed5ba34ccfc864866bb4e.tar.gz
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.c32
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;
}