diff options
author | Elliott Hughes <enh@google.com> | 2016-11-14 13:56:32 -0800 |
---|---|---|
committer | Abhisek Devkota <ciwrl@lineageos.org> | 2017-03-23 04:20:59 +0000 |
commit | a5e188eeca2a475da007d1d404497e0f4b61084b (patch) | |
tree | ecb312aef46748f416bb10977553d7352f3f53fc | |
parent | 51bb907af0091a265e2d373ddd5487e3839e1a4f (diff) | |
download | android_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.c | 7 | ||||
-rw-r--r-- | libc/netbsd/net/getaddrinfo.c | 18 |
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; |