From 71c95317195ed00602007b280e1cc8dee25d12fc Mon Sep 17 00:00:00 2001 From: roy Date: Fri, 6 Apr 2018 10:46:37 +0000 Subject: [PATCH] Import dhcpcd-7.0.3 with the following changes: * dhcp6: fix a null termination overflow on status messages * options: static routes can be setup in global context again * routes: dhcpcd added host routes are now reported correctly --- external/bsd/dhcpcd/dist/src/defs.h | 2 +- external/bsd/dhcpcd/dist/src/dhcp6.c | 11 +++--- external/bsd/dhcpcd/dist/src/dhcpcd.c | 24 +++++++------ external/bsd/dhcpcd/dist/src/if-options.c | 27 ++++---------- external/bsd/dhcpcd/dist/src/if-options.h | 2 +- external/bsd/dhcpcd/dist/src/if.c | 2 +- external/bsd/dhcpcd/dist/src/ipv4.c | 6 ++-- external/bsd/dhcpcd/dist/src/route.c | 44 +++++++++++++++++------ external/bsd/dhcpcd/dist/src/route.h | 3 ++ 9 files changed, 71 insertions(+), 50 deletions(-) diff --git a/external/bsd/dhcpcd/dist/src/defs.h b/external/bsd/dhcpcd/dist/src/defs.h index e2979b1faedc..cbc2c8ac1ff4 100644 --- a/external/bsd/dhcpcd/dist/src/defs.h +++ b/external/bsd/dhcpcd/dist/src/defs.h @@ -28,7 +28,7 @@ #define CONFIG_H #define PACKAGE "dhcpcd" -#define VERSION "7.0.2" +#define VERSION "7.0.3" #ifndef CONFIG # define CONFIG SYSCONFDIR "/" PACKAGE ".conf" diff --git a/external/bsd/dhcpcd/dist/src/dhcp6.c b/external/bsd/dhcpcd/dist/src/dhcp6.c index 08b9f283119a..89f71d79a795 100644 --- a/external/bsd/dhcpcd/dist/src/dhcp6.c +++ b/external/bsd/dhcpcd/dist/src/dhcp6.c @@ -1847,6 +1847,7 @@ dhcp6_checkstatusok(const struct interface *ifp, { uint8_t *opt; uint16_t opt_len, code; + size_t mlen; void * (*f)(void *, size_t, uint16_t, uint16_t *), *farg; char buf[32], *sbuf; const char *status; @@ -1872,8 +1873,8 @@ dhcp6_checkstatusok(const struct interface *ifp, /* Anything after the code is a message. */ opt += sizeof(code); - opt_len = (uint16_t)(opt_len - sizeof(code)); - if (opt_len == 0) { + mlen = opt_len - sizeof(code); + if (mlen == 0) { sbuf = NULL; if (code < sizeof(dhcp6_statuses) / sizeof(char *)) status = dhcp6_statuses[code]; @@ -1882,12 +1883,12 @@ dhcp6_checkstatusok(const struct interface *ifp, status = buf; } } else { - if ((sbuf = malloc((size_t)opt_len + 1)) == NULL) { + if ((sbuf = malloc(mlen + 1)) == NULL) { logerr(__func__); return -1; } - memcpy(sbuf, opt, opt_len); - sbuf[len] = '\0'; + memcpy(sbuf, opt, mlen); + sbuf[mlen] = '\0'; status = sbuf; } diff --git a/external/bsd/dhcpcd/dist/src/dhcpcd.c b/external/bsd/dhcpcd/dist/src/dhcpcd.c index 8b35ee59a70c..4944c00f5373 100644 --- a/external/bsd/dhcpcd/dist/src/dhcpcd.c +++ b/external/bsd/dhcpcd/dist/src/dhcpcd.c @@ -577,7 +577,7 @@ dhcpcd_selectprofile(struct interface *ifp, const char *profile) } else *ifp->profile = '\0'; - free_options(ifp->options); + free_options(ifp->ctx, ifp->options); ifp->options = ifo; if (profile) { add_options(ifp->ctx, ifp->name, ifp->options, @@ -995,6 +995,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname) } /* Check if we already have the interface */ iff = if_find(ctx->ifaces, ifp->name); + if (iff != NULL) { if (iff->active) logdebugx("%s: interface updated", iff->name); @@ -1013,9 +1014,12 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname) } iff = ifp; } - if_learnaddrs(ctx, ifs, &ifaddrs); - if (action > 0 && iff->active) - dhcpcd_prestartinterface(iff); + + if (action > 0) { + if_learnaddrs(ctx, ifs, &ifaddrs); + if (iff->active) + dhcpcd_prestartinterface(iff); + } /* Free our discovered list */ while ((ifp = TAILQ_FIRST(ifs))) { @@ -1161,7 +1165,7 @@ reload_config(struct dhcpcd_ctx *ctx) if (ctx->options & DHCPCD_DAEMONISED) ifo->options |= DHCPCD_DAEMONISED; ctx->options = ifo->options; - free_options(ifo); + free_options(ctx, ifo); } static void @@ -1519,6 +1523,8 @@ main(int argc, char **argv) #ifdef INET ctx.udp_fd = -1; #endif + rt_init(&ctx); + logopts = LOGERR_ERR|LOGERR_LOG|LOGERR_LOG_DATE|LOGERR_LOG_PID; i = 0; while ((opt = getopt_long(argc, argv, @@ -1613,7 +1619,7 @@ main(int argc, char **argv) if (i == 2) { printf("Interface options:\n"); if (optind == argc - 1) { - free_options(ifo); + free_options(&ctx, ifo); ifo = read_config(&ctx, argv[optind], NULL, NULL); if (ifo == NULL) goto exit_failure; @@ -1929,8 +1935,6 @@ printpidfile: } } - rt_init(&ctx); - TAILQ_FOREACH(ifp, ctx.ifaces, next) { if (ifp->active) dhcpcd_initstate1(ifp, argc, argv, 0); @@ -1981,7 +1985,7 @@ printpidfile: handle_exit_timeout, &ctx); } } - free_options(ifo); + free_options(&ctx, ifo); ifo = NULL; if_sortinterfaces(&ctx); @@ -2018,6 +2022,7 @@ exit1: } free(ctx.ifaces); } + free_options(&ctx, ifo); rt_dispose(&ctx); free(ctx.duid); if (ctx.link_fd != -1) { @@ -2025,7 +2030,6 @@ exit1: close(ctx.link_fd); } if_closesockets(&ctx); - free_options(ifo); free_globals(&ctx); ipv6_ctxfree(&ctx); dev_stop(&ctx); diff --git a/external/bsd/dhcpcd/dist/src/if-options.c b/external/bsd/dhcpcd/dist/src/if-options.c index 40a7e7a53256..d0feadddfd96 100644 --- a/external/bsd/dhcpcd/dist/src/if-options.c +++ b/external/bsd/dhcpcd/dist/src/if-options.c @@ -1086,14 +1086,8 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, strncmp(arg, "ms_classless_static_routes=", strlen("ms_classless_static_routes=")) == 0) { - struct interface *ifp; struct in_addr addr3; - ifp = if_find(ctx->ifaces, ifname); - if (ifp == NULL) { - logerrx("static routes require an interface"); - return -1; - } fp = np = strwhite(p); if (np == NULL) { logerrx("all routes need a gateway"); @@ -1107,7 +1101,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, *fp = ' '; return -1; } - if ((rt = rt_new(ifp)) == NULL) { + if ((rt = rt_new0(ctx)) == NULL) { *fp = ' '; return -1; } @@ -1117,16 +1111,9 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, TAILQ_INSERT_TAIL(&ifo->routes, rt, rt_next); *fp = ' '; } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) { - struct interface *ifp; - - ifp = if_find(ctx->ifaces, ifname); - if (ifp == NULL) { - logerrx("static routes require an interface"); - return -1; - } if (parse_addr(&addr, NULL, p) == -1) return -1; - if ((rt = rt_new(ifp)) == NULL) + if ((rt = rt_new0(ctx)) == NULL) return -1; addr2.s_addr = INADDR_ANY; sa_in_init(&rt->rt_dest, &addr2); @@ -2367,7 +2354,7 @@ read_config(struct dhcpcd_ctx *ctx, buf = malloc(buflen); if (buf == NULL) { logerr(__func__); - free_options(ifo); + free_options(ctx, ifo); return NULL; } ldop = edop = NULL; @@ -2381,7 +2368,7 @@ read_config(struct dhcpcd_ctx *ctx, if (nbuf == NULL) { logerr(__func__); free(buf); - free_options(ifo); + free_options(ctx, ifo); return NULL; } buf = nbuf; @@ -2545,7 +2532,7 @@ read_config(struct dhcpcd_ctx *ctx, free(buf); if (profile && !have_profile) { - free_options(ifo); + free_options(ctx, ifo); errno = ENOENT; return NULL; } @@ -2590,7 +2577,7 @@ add_options(struct dhcpcd_ctx *ctx, const char *ifname, } void -free_options(struct if_options *ifo) +free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo) { size_t i; struct dhcp_opt *opt; @@ -2612,7 +2599,7 @@ free_options(struct if_options *ifo) free(ifo->config[i++]); free(ifo->config); } - rt_headclear(&ifo->routes, AF_UNSPEC); + rt_headclear0(ctx, &ifo->routes, AF_UNSPEC); free(ifo->script); free(ifo->arping); free(ifo->blacklist); diff --git a/external/bsd/dhcpcd/dist/src/if-options.h b/external/bsd/dhcpcd/dist/src/if-options.h index 4852d4b761c7..8dfe3486e946 100644 --- a/external/bsd/dhcpcd/dist/src/if-options.h +++ b/external/bsd/dhcpcd/dist/src/if-options.h @@ -230,6 +230,6 @@ struct if_options *read_config(struct dhcpcd_ctx *, int add_options(struct dhcpcd_ctx *, const char *, struct if_options *, int, char **); void free_dhcp_opt_embenc(struct dhcp_opt *); -void free_options(struct if_options *); +void free_options(struct dhcpcd_ctx *, struct if_options *); #endif diff --git a/external/bsd/dhcpcd/dist/src/if.c b/external/bsd/dhcpcd/dist/src/if.c index 208da245e8af..eaebefa5a4e3 100644 --- a/external/bsd/dhcpcd/dist/src/if.c +++ b/external/bsd/dhcpcd/dist/src/if.c @@ -85,7 +85,7 @@ if_free(struct interface *ifp) ipv6nd_free(ifp); ipv6_free(ifp); rt_freeif(ifp); - free_options(ifp->options); + free_options(ifp->ctx, ifp->options); free(ifp); } diff --git a/external/bsd/dhcpcd/dist/src/ipv4.c b/external/bsd/dhcpcd/dist/src/ipv4.c index d40b3f632566..0a2594b88c38 100644 --- a/external/bsd/dhcpcd/dist/src/ipv4.c +++ b/external/bsd/dhcpcd/dist/src/ipv4.c @@ -289,10 +289,11 @@ inet_dhcproutes(struct rt_head *routes, struct interface *ifp) TAILQ_FOREACH(r, &ifp->options->routes, rt_next) { if (sa_is_unspecified(&r->rt_gateway)) break; - if ((rt = rt_new(ifp)) == NULL) + if ((rt = rt_new0(ifp->ctx)) == NULL) return -1; - rt->rt_dflags = RTDF_STATIC; memcpy(rt, r, sizeof(*rt)); + rt_setif(rt, ifp); + rt->rt_dflags = RTDF_STATIC; TAILQ_INSERT_TAIL(&nroutes, rt, rt_next); } } else { @@ -407,6 +408,7 @@ inet_routerhostroute(struct rt_head *routes, struct interface *ifp) } if ((rth = rt_new(ifp)) == NULL) return -1; + rth->rt_flags |= RTF_HOST; sa_in_init(&rth->rt_dest, &gateway->sin_addr); in.s_addr = INADDR_BROADCAST; sa_in_init(&rth->rt_netmask, &in); diff --git a/external/bsd/dhcpcd/dist/src/route.c b/external/bsd/dhcpcd/dist/src/route.c index 70d8868bccf4..dc43a8c0f973 100644 --- a/external/bsd/dhcpcd/dist/src/route.c +++ b/external/bsd/dhcpcd/dist/src/route.c @@ -101,17 +101,13 @@ rt_desc(const char *cmd, const struct rt *rt) } void -rt_headclear(struct rt_head *rts, int af) +rt_headclear0(struct dhcpcd_ctx *ctx, struct rt_head *rts, int af) { struct rt *rt, *rtn; - struct dhcpcd_ctx *ctx; if (rts == NULL) return; - - if ((rt = TAILQ_FIRST(rts)) == NULL) - return; - ctx = rt->rt_ifp->ctx; + assert(ctx != NULL); assert(&ctx->froutes != rts); TAILQ_FOREACH_SAFE(rt, rts, rt_next, rtn) { @@ -124,6 +120,16 @@ rt_headclear(struct rt_head *rts, int af) } } +void +rt_headclear(struct rt_head *rts, int af) +{ + struct rt *rt; + + if (rts == NULL || (rt = TAILQ_FIRST(rts)) == NULL) + return; + rt_headclear0(rt->rt_ifp->ctx, rts, af); +} + static void rt_headfree(struct rt_head *rts) { @@ -146,13 +152,11 @@ rt_dispose(struct dhcpcd_ctx *ctx) } struct rt * -rt_new(struct interface *ifp) +rt_new0(struct dhcpcd_ctx *ctx) { struct rt *rt; - struct dhcpcd_ctx *ctx; - assert(ifp != NULL); - ctx = ifp->ctx; + assert(ctx != NULL); if ((rt = TAILQ_FIRST(&ctx->froutes)) != NULL) TAILQ_REMOVE(&ctx->froutes, rt, rt_next); else if ((rt = malloc(sizeof(*rt))) == NULL) { @@ -160,10 +164,30 @@ rt_new(struct interface *ifp) return NULL; } memset(rt, 0, sizeof(*rt)); + return rt; +} + +void +rt_setif(struct rt *rt, struct interface *ifp) +{ + + assert(rt != NULL); + assert(ifp != NULL); rt->rt_ifp = ifp; #ifdef HAVE_ROUTE_METRIC rt->rt_metric = ifp->metric; #endif +} + +struct rt * +rt_new(struct interface *ifp) +{ + struct rt *rt; + + assert(ifp != NULL); + if ((rt = rt_new0(ifp->ctx)) == NULL) + return NULL; + rt_setif(rt, ifp); return rt; } diff --git a/external/bsd/dhcpcd/dist/src/route.h b/external/bsd/dhcpcd/dist/src/route.h index 160f6ff921b8..204b20c0b2d2 100644 --- a/external/bsd/dhcpcd/dist/src/route.h +++ b/external/bsd/dhcpcd/dist/src/route.h @@ -86,8 +86,11 @@ void rt_dispose(struct dhcpcd_ctx *); struct rt * rt_find(struct rt_head *, const struct rt *); void rt_free(struct rt *); void rt_freeif(struct interface *); +void rt_headclear0(struct dhcpcd_ctx *, struct rt_head *, int); void rt_headclear(struct rt_head *, int); void rt_headfreeif(struct rt_head *); +struct rt * rt_new0(struct dhcpcd_ctx *); +void rt_setif(struct rt *, struct interface *); struct rt * rt_new(struct interface *); void rt_recvrt(int, const struct rt *); void rt_build(struct dhcpcd_ctx *, int);