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
This commit is contained in:
parent
6909e9fcde
commit
71c9531719
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue