diff options
author | Selim Gurun <sgurun@google.com> | 2012-02-27 15:58:54 -0800 |
---|---|---|
committer | Selim Gurun <sgurun@google.com> | 2012-03-07 15:09:05 -0800 |
commit | 06e1831f194389b6f56ac016ebb52ed5cd430bb2 (patch) | |
tree | 1bae36f75baac7fd29c053323e6f17af609ec573 /libc | |
parent | 83c366cf093b068da38e24e4ae4525c015ddde20 (diff) | |
download | bionic-06e1831f194389b6f56ac016ebb52ed5cd430bb2.zip bionic-06e1831f194389b6f56ac016ebb52ed5cd430bb2.tar.gz bionic-06e1831f194389b6f56ac016ebb52ed5cd430bb2.tar.bz2 |
Prevent potential stall on dns proxy operations.
Update wire protocol to return and process error code first.
This will make sure dns proxy operations do not stall when
an internal error happens.
Also fix a compiler warning.
Also fix a potential buffer overflow.
And use correct types (uint32_t) rather than int when reading from network.
Change-Id: I9f99c16d6fd5e9137491a4d1b293a7c78e31b9c3
Diffstat (limited to 'libc')
-rw-r--r-- | libc/netbsd/net/getaddrinfo.c | 12 | ||||
-rw-r--r-- | libc/netbsd/net/getnameinfo.c | 36 |
2 files changed, 36 insertions, 12 deletions
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 @@ static const char in6_loopback[] = { }; #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 @@ android_getaddrinfo_proxy( 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 @@ static int getnameinfo_link __P((const struct sockaddr *, socklen_t, char *, 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 @@ int getnameinfo(const struct sockaddr* sa, socklen_t salen, char* host, size_t h * 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 @@ android_gethostbyaddr_proxy(struct hostent* hp, const void *addr, socklen_t addr } 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 @@ android_gethostbyaddr_proxy(struct hostent* hp, const void *addr, socklen_t addr } 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 @@ getnameinfo_inet(sa, salen, host, hostlen, serv, servlen, flags) #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); } |