Module Name:    src
Committed By:   christos
Date:           Fri Jan 17 02:03:44 UTC 2014

Modified Files:
        src/lib/libc/net: gethnamaddr.c

Log Message:
Move more code into the macro, and fix the bug where realloc would cause
a dangling pointer and memory corruption.


To generate a diff of this commit:
cvs rdiff -u -r1.86 -r1.87 src/lib/libc/net/gethnamaddr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/net/gethnamaddr.c
diff -u src/lib/libc/net/gethnamaddr.c:1.86 src/lib/libc/net/gethnamaddr.c:1.87
--- src/lib/libc/net/gethnamaddr.c:1.86	Thu Jan 16 15:59:21 2014
+++ src/lib/libc/net/gethnamaddr.c	Thu Jan 16 21:03:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: gethnamaddr.c,v 1.86 2014/01/16 20:59:21 christos Exp $	*/
+/*	$NetBSD: gethnamaddr.c,v 1.87 2014/01/17 02:03:44 christos Exp $	*/
 
 /*
  * ++Copyright++ 1985, 1988, 1993
@@ -57,7 +57,7 @@
 static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93";
 static char rcsid[] = "Id: gethnamaddr.c,v 8.21 1997/06/01 20:34:37 vixie Exp ";
 #else
-__RCSID("$NetBSD: gethnamaddr.c,v 1.86 2014/01/16 20:59:21 christos Exp $");
+__RCSID("$NetBSD: gethnamaddr.c,v 1.87 2014/01/17 02:03:44 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -108,18 +108,22 @@ __weak_alias(gethostent,_gethostent)
 #define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
 #define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
 
-#define grow(arr, siz) do {			\
-	void *xptr = realloc(arr, siz + 10); 	\
-	if (xptr == NULL)			\
-		goto nospc;			\
-	arr = xptr;				\
-	siz += 10;				\
+#define addalias(d, s, arr, siz) do {			\
+	if (d >= &arr[siz - 1]) {			\
+		char **xptr = realloc(arr, siz + 10); 	\
+		if (xptr == NULL)			\
+			goto nospc;			\
+		d = xptr + (d - arr);			\
+		arr = xptr;				\
+		siz += 10;				\
+	}						\
+	*d++ = s;					\
 } while (/*CONSTCOND*/0)
 
-#define setup(arr, siz) do {			\
-	arr = malloc(siz = 10); 		\
-	if (arr == NULL)			\
-		goto nospc;			\
+#define setup(arr, siz) do {				\
+	arr = malloc(siz = 10); 			\
+	if (arr == NULL)				\
+		goto nospc;				\
 } while (/*CONSTCOND*/0)
 
 
@@ -307,8 +311,6 @@ getanswer(const querybuf *answer, int an
 			continue;		/* XXX - had_error++ ? */
 		}
 		if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
-			if (ap >= &aliases[maxaliases - 1])
-				grow(aliases, maxaliases);
 			n = dn_expand(answer->buf, eom, cp, tbuf,
 			    (int)sizeof tbuf);
 			if ((n < 0) || !maybe_ok(res, tbuf, name_ok)) {
@@ -319,7 +321,7 @@ getanswer(const querybuf *answer, int an
 			if (cp != erdata)
 				goto no_recovery;
 			/* Store alias. */
-			*ap++ = bp;
+			addalias(ap, bp, aliases, maxaliases);
 			n = (int)strlen(bp) + 1;	/* for the \0 */
 			if (n >= MAXHOSTNAMELEN) {
 				had_error++;
@@ -386,11 +388,8 @@ getanswer(const querybuf *answer, int an
 				goto no_recovery;
 			if (!haveanswer)
 				hent->h_name = bp;
-			else {
-				if (ap >= &aliases[maxaliases - 1])
-					grow(aliases, maxaliases);
-				*ap++ = bp;
-			}
+			else
+				addalias(ap, bp, aliases, maxaliases);
 			if (n != -1) {
 				n = (int)strlen(bp) + 1;	/* for the \0 */
 				if (n >= MAXHOSTNAMELEN) {
@@ -808,8 +807,7 @@ gethostent_r(FILE *hf, struct hostent *h
 			cp++;
 			continue;
 		}
-		if (q >= &aliases[maxaliases - 1])
-			grow(aliases, maxaliases);
+		addalias(q, cp, aliases, maxaliases);
 		*q++ = cp;
 		if ((cp = strpbrk(cp, " \t")) != NULL)
 			*cp++ = '\0';
@@ -1173,11 +1171,8 @@ nextline:
 		hp->h_name = p;
 	else if (strcmp(hp->h_name, p) == 0)
 		;
-	else {
-		if (q >= &aliases[maxaliases - 1])
-			grow(aliases, maxaliases);
-		*q++ = p;
-	}
+	else
+		addalias(q, p, aliases, maxaliases);
 	p = cp;
 	if (more)
 		goto nextline;
@@ -1191,8 +1186,7 @@ nextline:
 			cp++;
 			goto nextline;
 		}
-		if (q >= &aliases[maxaliases - 1])
-			grow(aliases, maxaliases);
+		addalias(q, cp, aliases, maxaliases);
 		*q++ = cp;
 		cp = strpbrk(cp, " \t");
 		if (cp != NULL)

Reply via email to