aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2016-11-14 13:56:32 -0800
committerAbhisek Devkota <ciwrl@lineageos.org>2017-03-23 04:20:59 +0000
commita5e188eeca2a475da007d1d404497e0f4b61084b (patch)
treeecb312aef46748f416bb10977553d7352f3f53fc
parent51bb907af0091a265e2d373ddd5487e3839e1a4f (diff)
downloadandroid_bionic-cm-11.0.tar.gz
android_bionic-cm-11.0.tar.bz2
android_bionic-cm-11.0.zip
Check for bad packets in getaddrinfo.c's getanswer.cm-11.0
The near duplicate in gethnamaddr.c was already doing so (this fix is basically copy and pasted from there, but with both copies modified to avoid skirting undefined behavior). Bug: 32322088 Test: browser still works Change-Id: Ied6662be567fb1bddc7ceb138cae1da77fb57976 (cherry picked from commit 27a4459d945e34fabd7166791a5b862ccea83f23) (cherry picked from commit 418fe1eb1aeefc2268a40c5cec0ceb62672fa026) (cherry picked from commit 0f6bfb7068224ecc7e80c9b91bffa3dfa912b4e9)
-rw-r--r--libc/netbsd/gethnamaddr.c7
-rw-r--r--libc/netbsd/net/getaddrinfo.c18
2 files changed, 18 insertions, 7 deletions
diff --git a/libc/netbsd/gethnamaddr.c b/libc/netbsd/gethnamaddr.c
index 5b2f98750..c86d58dea 100644
--- a/libc/netbsd/gethnamaddr.c
+++ b/libc/netbsd/gethnamaddr.c
@@ -159,15 +159,12 @@ dprintf(const char *msg, res_state res, ...)
#define BOUNDED_INCR(x) \
do { \
cp += (x); \
- if (cp > eom) { \
- h_errno = NO_RECOVERY; \
- return NULL; \
- } \
+ BOUNDS_CHECK(cp, x); \
} 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/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index 937c42350..e0ee156dd 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -1292,6 +1292,17 @@ ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
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)
@@ -1337,7 +1348,8 @@ getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
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);
@@ -1347,7 +1359,7 @@ getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
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
@@ -1372,12 +1384,14 @@ getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
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;