Check for bad packets in getaddrinfo.c's getanswer.
am: 9ea3f1c8a5

Change-Id: Id6ba716299450f0f0625750460524fa07f55e708
diff --git a/libc/dns/gethnamaddr.c b/libc/dns/gethnamaddr.c
index 1d847b8..674b3cb 100644
--- a/libc/dns/gethnamaddr.c
+++ b/libc/dns/gethnamaddr.c
@@ -163,16 +163,13 @@
 
 #define BOUNDED_INCR(x) \
 	do { \
+		BOUNDS_CHECK(cp, (x)); \
 		cp += (x); \
-		if (cp > eom) { \
-			h_errno = NO_RECOVERY; \
-			return NULL; \
-		} \
 	} while (/*CONSTCOND*/0)
 
 #define BOUNDS_CHECK(ptr, count) \
 	do { \
-		if ((ptr) + (count) > eom) { \
+		if (eom - (ptr) < (count)) { \
 			h_errno = NO_RECOVERY; \
 			return NULL; \
 		} \
diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c
index 2612d6a..7e36c20 100644
--- a/libc/dns/net/getaddrinfo.c
+++ b/libc/dns/net/getaddrinfo.c
@@ -1299,6 +1299,17 @@
 static const char AskedForGot[] =
 	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
 
+#define BOUNDED_INCR(x) \
+	do { \
+		BOUNDS_CHECK(cp, x); \
+		cp += (x); \
+	} while (/*CONSTCOND*/0)
+
+#define BOUNDS_CHECK(ptr, count) \
+	do { \
+		if (eom - (ptr) < (count)) { h_errno = NO_RECOVERY; return NULL; } \
+	} while (/*CONSTCOND*/0)
+
 static struct addrinfo *
 getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
     const struct addrinfo *pai)
@@ -1344,7 +1355,8 @@
 	qdcount = ntohs(hp->qdcount);
 	bp = hostbuf;
 	ep = hostbuf + sizeof hostbuf;
-	cp = answer->buf + HFIXEDSZ;
+	cp = answer->buf;
+	BOUNDED_INCR(HFIXEDSZ);
 	if (qdcount != 1) {
 		h_errno = NO_RECOVERY;
 		return (NULL);
@@ -1354,7 +1366,7 @@
 		h_errno = NO_RECOVERY;
 		return (NULL);
 	}
-	cp += n + QFIXEDSZ;
+	BOUNDED_INCR(n + QFIXEDSZ);
 	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
 		/* res_send() has already verified that the query name is the
 		 * same as the one we sent; this just gets the expanded name
@@ -1379,12 +1391,14 @@
 			continue;
 		}
 		cp += n;			/* name */
+		BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
 		type = _getshort(cp);
  		cp += INT16SZ;			/* type */
 		class = _getshort(cp);
  		cp += INT16SZ + INT32SZ;	/* class, TTL */
 		n = _getshort(cp);
 		cp += INT16SZ;			/* len */
+		BOUNDS_CHECK(cp, n);
 		if (class != C_IN) {
 			/* XXX - debug? syslog? */
 			cp += n;