]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
route: Free route when failing to insert.
authorRoy Marples <roy@marples.name>
Mon, 4 Mar 2019 14:34:59 +0000 (14:34 +0000)
committerRoy Marples <roy@marples.name>
Mon, 4 Mar 2019 14:34:59 +0000 (14:34 +0000)
This means the collection already has the route, so we avoid
leaking memory.

src/dhcp.c
src/if-options.c
src/ipv4.c
src/ipv4ll.c
src/ipv6.c
src/route.c

index b77eda164317f8e73ec58ec6dab840d4aa3e780a..73ca69f8ee8fd2bf6b38b2702ce370cfedfbf14f 100644 (file)
@@ -465,8 +465,10 @@ decode_rfc3442_rt(rb_tree_t *routes, struct interface *ifp,
                sa_in_init(&rt->rt_dest, &dest);
                sa_in_init(&rt->rt_netmask, &netmask);
                sa_in_init(&rt->rt_gateway, &gateway);
-               rb_tree_insert_node(routes, rt);
-               n++;
+               if (rb_tree_insert_node(routes, rt) != rt)
+                       rt_free(rt);
+               else
+                       n++;
        }
        return n;
 }
@@ -653,8 +655,10 @@ get_option_routes(rb_tree_t *routes, struct interface *ifp,
                        sa_in_init(&rt->rt_dest, &dest);
                        sa_in_init(&rt->rt_netmask, &netmask);
                        sa_in_init(&rt->rt_gateway, &gateway);
-                       rb_tree_insert_node(routes, rt);
-                       n++;
+                       if (rb_tree_insert_node(routes, rt) != rt)
+                               rt_free(rt);
+                       else
+                               n++;
                }
        }
 
@@ -675,8 +679,10 @@ get_option_routes(rb_tree_t *routes, struct interface *ifp,
                        sa_in_init(&rt->rt_dest, &dest);
                        sa_in_init(&rt->rt_netmask, &netmask);
                        sa_in_init(&rt->rt_gateway, &gateway);
-                       rb_tree_insert_node(routes, rt);
-                       n++;
+                       if (rb_tree_insert_node(routes, rt) != rt)
+                               rt_free(rt);
+                       else
+                               n++;
                }
        }
 
index 074912d42bb949373ca67df24dec38e046689e8c..273546299a623915f8b1c5a33440417649fb63a3 100644 (file)
@@ -1110,7 +1110,8 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
                        sa_in_init(&rt->rt_dest, &addr);
                        sa_in_init(&rt->rt_netmask, &addr2);
                        sa_in_init(&rt->rt_gateway, &addr3);
-                       rb_tree_insert_node(&ifo->routes, rt);
+                       if (rb_tree_insert_node(&ifo->routes, rt) != rt)
+                               rt_free(rt);
                        *fp = ' ';
                } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) {
                        if (parse_addr(&addr, NULL, p) == -1)
@@ -1121,7 +1122,8 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
                        sa_in_init(&rt->rt_dest, &addr2);
                        sa_in_init(&rt->rt_netmask, &addr2);
                        sa_in_init(&rt->rt_gateway, &addr);
-                       rb_tree_insert_node(&ifo->routes, rt);
+                       if (rb_tree_insert_node(&ifo->routes, rt) != rt)
+                               rt_free(rt);
                } else if (strncmp(arg, "interface_mtu=",
                    strlen("interface_mtu=")) == 0 ||
                    strncmp(arg, "mtu=", strlen("mtu=")) == 0)
index 1bdfc4c53a3a2159287e4101c15f212668508bd6..cdccf6ce1fddadcd91028ec3a5cefa223eb92410 100644 (file)
@@ -283,7 +283,8 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp)
                //in.s_addr = INADDR_ANY;
                //sa_in_init(&rt->rt_gateway, &in);
                rt->rt_gateway.sa_family = AF_UNSPEC;
-               rb_tree_insert_node(&nroutes, rt);
+               if (rb_tree_insert_node(&nroutes, rt) != rt)
+                       rt_free(rt);
        }
 
        /* If any set routes, grab them, otherwise DHCP routes. */
@@ -296,7 +297,8 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp)
                        memcpy(rt, r, sizeof(*rt));
                        rt_setif(rt, ifp);
                        rt->rt_dflags = RTDF_STATIC;
-                       rb_tree_insert_node(&nroutes, rt);
+                       if (rb_tree_insert_node(&nroutes, rt) != rt)
+                               rt_free(rt);
                }
        } else {
                if (dhcp_get_routes(&nroutes, ifp) == -1)
@@ -315,7 +317,8 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp)
                sa_in_init(&rt->rt_netmask, &in);
                sa_in_init(&rt->rt_gateway, &state->addr->brd);
                sa_in_init(&rt->rt_ifa, &state->addr->addr);
-               rb_tree_insert_node(&nroutes, rt);
+               if (rb_tree_insert_node(&nroutes, rt) != rt)
+                       rt_free(rt);
        }
 
        /* Copy our address as the source address and set mtu */
@@ -327,8 +330,10 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp)
                if (!(rt->rt_dflags & RTDF_STATIC))
                        rt->rt_dflags |= RTDF_DHCP;
                sa_in_init(&rt->rt_ifa, &state->addr->addr);
-               rb_tree_insert_node(routes, rt);
-               n++;
+               if (rb_tree_insert_node(routes, rt) != rt)
+                       rt_free(rt);
+               else
+                       n++;
        }
 
        return n;
@@ -420,7 +425,8 @@ inet_routerhostroute(rb_tree_t *routes, struct interface *ifp)
                sa_in_init(&rth->rt_gateway, &in);
                rth->rt_mtu = dhcp_get_mtu(ifp);
                sa_in_init(&rth->rt_ifa, &state->addr->addr);
-               rb_tree_insert_node(routes, rth);
+               if (rb_tree_insert_node(routes, rth) != rth)
+                       rt_free(rth);
        }
        return 0;
 }
index 673f583d31930bd697a829a950ce6583585fc3ee..5ae3d4859056a443bb8ad209426f43711d3771b5 100644 (file)
@@ -108,7 +108,10 @@ ipv4ll_subnetroute(rb_tree_t *routes, struct interface *ifp)
        in.s_addr = INADDR_ANY;
        sa_in_init(&rt->rt_gateway, &in);
        sa_in_init(&rt->rt_ifa, &state->addr->addr);
-       rb_tree_insert_node(routes, rt);
+       if (rb_tree_insert_node(routes, rt) != rt) {
+               rt_free(rt);
+               return 0;
+       }
        return 1;
 }
 
@@ -132,7 +135,10 @@ ipv4ll_defaultroute(rb_tree_t *routes, struct interface *ifp)
        sa_in_init(&rt->rt_netmask, &in);
        sa_in_init(&rt->rt_gateway, &in);
        sa_in_init(&rt->rt_ifa, &state->addr->addr);
-       rb_tree_insert_node(routes, rt);
+       if (rb_tree_insert_node(routes, rt) != rt) {
+               rt_free(rt);
+               return 0;
+       }
        return 1;
 }
 
index f078972c82c23d13a534efc328bc7cf17b5ebda2..ee62633085b5d043979ed57433af21a4df6db2f8 100644 (file)
@@ -2223,8 +2223,8 @@ inet6_staticroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx)
                            (IPV6_AF_ADDED | IPV6_AF_STATIC))
                        {
                                rt = inet6_makeprefix(ifp, NULL, ia);
-                               if (rt)
-                                       rb_tree_insert_node(routes, rt);
+                               if (rt && rb_tree_insert_node(routes, rt) != rt)
+                                       rt_free(rt);
                        }
                }
        }
@@ -2248,15 +2248,17 @@ inet6_raroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx, int expired,
                        rt = inet6_makeprefix(rap->iface, rap, addr);
                        if (rt) {
                                rt->rt_dflags |= RTDF_RA;
-                               rb_tree_insert_node(routes, rt);
+                               if (rb_tree_insert_node(routes, rt) != rt)
+                                       rt_free(rt);
                        }
                }
                if (rap->lifetime) {
                        rt = inet6_makerouter(rap);
                        if (rt) {
                                rt->rt_dflags |= RTDF_RA;
-                               rb_tree_insert_node(routes, rt);
-                               if (have_default)
+                               if (rb_tree_insert_node(routes, rt) != rt)
+                                       rt_free(rt);
+                               else if (have_default)
                                        *have_default = true;
                        }
                }
@@ -2282,7 +2284,8 @@ inet6_dhcproutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx,
                                if (rt == NULL)
                                        continue;
                                rt->rt_dflags |= RTDF_DHCP;
-                               rb_tree_insert_node(routes, rt);
+                               if (rb_tree_insert_node(routes, rt) != rt)
+                                       rt_free(rt);
                        }
                }
        }
index 0015ff3626417c1717a33d43c64e501c45439272..d7cfe7ba730fbb09cb88d22c83a86599c770c18a 100644 (file)
@@ -354,10 +354,10 @@ rt_recvrt(int cmd, const struct rt *rt)
        assert(rt->rt_ifp->ctx != NULL);
 
        ctx = rt->rt_ifp->ctx;
-       f = rb_tree_find_node(&ctx->kroutes, rt);
 
        switch(cmd) {
        case RTM_DELETE:
+               f = rb_tree_find_node(&ctx->kroutes, rt);
                if (f != NULL) {
                        rb_tree_remove_node(&ctx->kroutes, f);
                        rt_free(f);
@@ -370,12 +370,11 @@ rt_recvrt(int cmd, const struct rt *rt)
                }
                break;
        case RTM_ADD:
-               if (f != NULL)
-                       break;
                if ((f = rt_new(rt->rt_ifp)) == NULL)
                        break;
                memcpy(f, rt, sizeof(*f));
-               rb_tree_insert_node(&ctx->kroutes, f);
+               if (rb_tree_insert_node(&ctx->kroutes, f) != f)
+                       rt_free(f);
                break;
        }
 
@@ -607,7 +606,11 @@ rt_build(struct dhcpcd_ctx *ctx, int af)
                        continue;
                if (rt_doroute(rt)) {
                        rb_tree_remove_node(&routes, rt);
-                       rb_tree_insert_node(&added, rt);
+                       if (rb_tree_insert_node(&added, rt) != rt) {
+                               errno = EEXIST;
+                               logerr(__func__);
+                               rt_free(rt);
+                       }
                }
        }
 
@@ -632,7 +635,11 @@ rt_build(struct dhcpcd_ctx *ctx, int af)
        /* XXX This needs to be optimised. */
        while ((rt = RB_TREE_MIN(&added)) != NULL) {
                rb_tree_remove_node(&added, rt);
-               rb_tree_insert_node(&ctx->routes, rt);
+               if (rb_tree_insert_node(&ctx->routes, rt) != rt) {
+                       errno = EEXIST;
+                       logerr(__func__);
+                       rt_free(rt);
+               }
        }
 
 getfail: