]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Fix some memory errors
authorRoy Marples <roy@marples.name>
Wed, 4 Dec 2013 10:48:22 +0000 (10:48 +0000)
committerRoy Marples <roy@marples.name>
Wed, 4 Dec 2013 10:48:22 +0000 (10:48 +0000)
dhcp-common.c
dhcp6.c

index 2a87361df669d1f679725df81bb4f1081c3eac51..ad8fa1d2d7f74ba122423996a7a2241504f9e476 100644 (file)
@@ -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 09a0ed69292f9ee77f26d7f744bfcd1d8bd8e884..db70d197229ec90d2e2944028a1369de284b99cd 100644 (file)
--- 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;