Merge "Prevent potential stall on dns proxy operations."
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index 6ae6e3e..7dd65ff 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -130,6 +130,9 @@
 };
 #endif
 
+// This should be synchronized to ResponseCode.h
+static const int DnsProxyQueryResult = 222;
+
 static const struct afd {
 	int a_af;
 	int a_addrlen;
@@ -476,12 +479,15 @@
 		goto exit;
 	}
 
-	int remote_rv;
-	if (fread(&remote_rv, sizeof(int), 1, proxy) != 1) {
+	char buf[5];
+	// read result code for gethostbyaddr
+	if (fread(buf, 1, sizeof(buf), proxy) != sizeof(buf)) {
 		goto exit;
 	}
 
-	if (remote_rv != 0) {
+	int result_code = (int)strtol(buf, NULL, 10);
+	// verify the code itself
+	if (result_code != DnsProxyQueryResult ) {
 		goto exit;
 	}
 
diff --git a/libc/netbsd/net/getnameinfo.c b/libc/netbsd/net/getnameinfo.c
index d3d0011..eed23a7 100644
--- a/libc/netbsd/net/getnameinfo.c
+++ b/libc/netbsd/net/getnameinfo.c
@@ -108,6 +108,10 @@
     socklen_t, char *, socklen_t, int));
 static int hexname __P((const u_int8_t *, size_t, char *, socklen_t));
 
+// This should be synchronized to ResponseCode.h
+static const int DnsProxyQueryResult = 222;
+
+
 /*
  * Top-level getnameinfo() code.  Look at the address family, and pick an
  * appropriate function to call.
@@ -135,7 +139,7 @@
  * the address. On failure -1 is returned in which case
  * normal execution flow shall continue. */
 static int
-android_gethostbyaddr_proxy(struct hostent* hp, const void *addr, socklen_t addrLen, int addrFamily) {
+android_gethostbyaddr_proxy(char* nameBuf, size_t nameBufLen, const void *addr, socklen_t addrLen, int addrFamily) {
 
 	int sock;
 	const int one = 1;
@@ -183,7 +187,7 @@
 	}
 
 	char buf[INET6_ADDRSTRLEN]; // big enough for IPv4 and IPv6
-	const char* addrStr = inet_ntop(addrFamily, addr, &buf, sizeof(buf));
+	const char* addrStr = inet_ntop(addrFamily, addr, buf, sizeof(buf));
 	if (addrStr == NULL) {
 		goto exit;
 	}
@@ -197,17 +201,29 @@
 	}
 
 	result = 0;
+	char msg_buf[5];
+	// read result code for gethostbyaddr
+	if (fread(msg_buf, 1, sizeof(msg_buf), proxy) != sizeof(msg_buf)) {
+		goto exit;
+	}
+
+	int result_code = (int)strtol(msg_buf, NULL, 10);
+	// verify the code itself
+	if (result_code != DnsProxyQueryResult) {
+		goto exit;
+	}
+
 	uint32_t name_len;
 	if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
 		goto exit;
 	}
 
 	name_len = ntohl(name_len);
-	if (name_len <= 0) {
+	if (name_len <= 0 || name_len >= nameBufLen) {
 		goto exit;
 	}
 
-	if (fread(hp->h_name, name_len, 1, proxy) != 1) {
+	if (fread(nameBuf, name_len, 1, proxy) != 1) {
 		goto exit;
 	}
 
@@ -376,12 +392,14 @@
 #ifdef ANDROID_CHANGES
 		struct hostent android_proxy_hostent;
 		char android_proxy_buf[MAXDNAME];
-		android_proxy_hostent.h_name = android_proxy_buf;
 
-		int hostnamelen = android_gethostbyaddr_proxy(&android_proxy_hostent,
-				addr, afd->a_addrlen, afd->a_af);
-		if (hostnamelen >= 0) {
-			hp = (hostnamelen > 0) ? &android_proxy_hostent : NULL;
+		int hostnamelen = android_gethostbyaddr_proxy(android_proxy_buf,
+				MAXDNAME, addr, afd->a_addrlen, afd->a_af);
+		if (hostnamelen > 0) {
+			hp = &android_proxy_hostent;
+			hp->h_name = android_proxy_buf;
+		} else if (!hostnamelen) {
+			hp = NULL;
 		} else {
 			hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
 		}