changeset 2190:2aca38b8b8bd draft

Fix some memory errors
author Roy Marples <roy@marples.name>
date Wed, 04 Dec 2013 10:48:22 +0000
parents 143b9d6bbddb
children 0b05aeb7dfc6
files dhcp-common.c dhcp6.c
diffstat 2 files changed, 29 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/dhcp-common.c	Tue Dec 03 23:38:00 2013 +0000
+++ b/dhcp-common.c	Wed Dec 04 10:48:22 2013 +0000
@@ -495,7 +495,7 @@
 	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 @@
 	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 @@
 		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 @@
 	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 @@
 			    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 @@
 						eopt = oopt;
 					}
 					n += dhcp_envoption(
-					    env == NULL ? NULL : &env[n], p,
+					    env == NULL ? NULL : &env[n], pfx,
 					    ifname, eopt,
 					    dgetopt, eod, eol);
 					break;
--- a/dhcp6.c	Tue Dec 03 23:38:00 2013 +0000
+++ b/dhcp6.c	Wed Dec 04 10:48:22 2013 +0000
@@ -2583,12 +2583,11 @@
 	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 @@
 		    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 @@
 	 * 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 @@
 				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 @@
 				*--v = '\0';
 			}
 		}
+		n++;
 	}
 
 	return n;