Check for bad packets in getaddrinfo.c's getanswer. am: 87c0dba7b1

am: dc0492ac4f

Change-Id: I949b993b8490d27ec180257fcca06d8984940f0f
This commit is contained in:
Elliott Hughes 2016-12-08 20:57:15 +00:00 committed by android-build-merger
commit f277bb86c6
2 changed files with 18 additions and 5 deletions

View file

@ -1290,6 +1290,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)
@ -1335,7 +1346,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);
@ -1345,7 +1357,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
@ -1370,12 +1382,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;

View file

@ -186,14 +186,13 @@ debugprintf(const char *msg, res_state res, ...)
#define BOUNDED_INCR(x) \
do { \
BOUNDS_CHECK(cp, x); \
cp += (x); \
if (cp > eom) \
goto no_recovery; \
} while (/*CONSTCOND*/0)
#define BOUNDS_CHECK(ptr, count) \
do { \
if ((ptr) + (count) > eom) \
if (eom - (ptr) < (count)) \
goto no_recovery; \
} while (/*CONSTCOND*/0)