From: Roy Marples Date: Wed, 4 Dec 2013 10:48:22 +0000 (+0000) Subject: Fix some memory errors X-Git-Tag: v6.2.0~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f8d2564f71415be896693a0e0af4ae8b7b4cc01;p=thirdparty%2Fdhcpcd.git Fix some memory errors --- diff --git a/dhcp-common.c b/dhcp-common.c index 2a87361d..ad8fa1d2 100644 --- a/dhcp-common.c +++ b/dhcp-common.c @@ -495,7 +495,7 @@ print_option(char *s, ssize_t len, int type, int dl, const uint8_t *data, return bytes; } -static ssize_t +static size_t dhcp_envoption1(char **env, const char *prefix, const struct dhcp_opt *opt, int vname, const uint8_t *od, int ol, const char *ifname) @@ -510,10 +510,14 @@ dhcp_envoption1(char **env, const char *prefix, if (len < 0) return 0; if (vname) - e = strlen(opt->v.var); + e = strlen(opt->v.var) + 1; else e = 0; - e += strlen(prefix) + len + 4; + if (prefix) + e += strlen(prefix); + e += len + 4; + if (env == NULL) + return e; v = val = *env = malloc(e); if (v == NULL) { syslog(LOG_ERR, "%s: %m", __func__); @@ -525,7 +529,7 @@ dhcp_envoption1(char **env, const char *prefix, v += snprintf(val, e, "%s=", prefix); if (len != 0) print_option(v, len, opt->type, ol, od, ifname); - return len; + return e; } ssize_t @@ -542,14 +546,13 @@ dhcp_envoption(char **env, const char *prefix, int eos, eol, ov; struct dhcp_opt *eopt, *oopt; char *pfx; - const char *p; /* If no embedded or encapsulated options, it's easy */ if (opt->embopts_len == 0 && opt->encopts_len == 0) { - if (env) - dhcp_envoption1(&env[0], prefix, opt, 1, od, ol, - ifname); - return 1; + if (dhcp_envoption1(env == NULL ? NULL : &env[0], + prefix, opt, 1, od, ol, ifname)) + return 1; + return 0; } /* Create a new prefix based on the option */ @@ -573,27 +576,24 @@ dhcp_envoption(char **env, const char *prefix, opt->v.var, ++opt->index); else snprintf(pfx, e, "%s_%s", prefix, opt->v.var); - p = pfx; } else - p = pfx = NULL; + pfx = NULL; /* Embedded options are always processed first as that * is a fixed layout */ n = 0; - for (i = 0, eopt = opt->embopts; i < opt->embopts_len; i++, eopt++) { e = dhcp_optlen(eopt, ol); if (e == 0) /* Report error? */ return 0; - if (env) { - /* Use the option prefix if the embedded option - * name is different. - * This avoids new_fqdn_fqdn which would be silly. */ - ov = strcmp(opt->v.var, eopt->v.var); - dhcp_envoption1(&env[n], p, eopt, ov, od, e, ifname); - } - n++; + /* Use the option prefix if the embedded option + * name is different. + * This avoids new_fqdn_fqdn which would be silly. */ + ov = strcmp(opt->v.var, eopt->v.var); + if (dhcp_envoption1(env == NULL ? NULL : &env[n], + pfx, eopt, ov, od, e, ifname)) + n++; od += e; ol -= e; } @@ -628,7 +628,7 @@ dhcp_envoption(char **env, const char *prefix, eopt = oopt; } n += dhcp_envoption( - env == NULL ? NULL : &env[n], p, + env == NULL ? NULL : &env[n], pfx, ifname, eopt, dgetopt, eod, eol); break; diff --git a/dhcp6.c b/dhcp6.c index 09a0ed69..db70d197 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -2583,12 +2583,11 @@ dhcp6_env(char **env, const char *prefix, const struct interface *ifp, const struct dhcp6_option *o; size_t i, n; uint16_t ol, oc; - char **ep, *v, *val, *pfx; + char *v, *val, *pfx; const struct ipv6_addr *ap; state = D6_CSTATE(ifp); n = 0; - ep = env; ifo = ifp->options; /* Zero our indexes */ @@ -2629,12 +2628,14 @@ dhcp6_env(char **env, const char *prefix, const struct interface *ifp, i++, opt++) if (opt->option == oc) break; - if (opt == NULL) { + if (i == ifo->dhcp6_override_len) { for (i = 0, opt = dhcp6_opts; i < dhcp6_opts_len; i++, opt++) if (opt->option == oc) break; + if (i == dhcp6_opts_len) + opt = NULL; } if (opt) { n += dhcp_envoption(env == NULL ? NULL : &env[n], @@ -2650,16 +2651,14 @@ dhcp6_env(char **env, const char *prefix, const struct interface *ifp, * and it's easier for shell scripts to see which addresses have * been added */ if (TAILQ_FIRST(&state->addrs)) { - if (env == NULL) - n++; - else { + if (env) { if (ifo->ia_type == D6_OPTION_IA_PD) { i = strlen(prefix) + strlen("_dhcp6_prefix="); TAILQ_FOREACH(ap, &state->addrs, next) { i += strlen(ap->saddr) + 1; } - v = val = *ep++ = malloc(i); + v = val = env[n] = malloc(i); if (v == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; @@ -2678,7 +2677,7 @@ dhcp6_env(char **env, const char *prefix, const struct interface *ifp, TAILQ_FOREACH(ap, &state->addrs, next) { i += strlen(ap->saddr) + 1; } - v = val = *ep++ = malloc(i); + v = val = env[n] = malloc(i); if (v == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; @@ -2693,6 +2692,7 @@ dhcp6_env(char **env, const char *prefix, const struct interface *ifp, *--v = '\0'; } } + n++; } return n;