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);
}