Include more robust checking of end of buffer that more completely
plugs the hole.
This commit is contained in:
parent
126b0a6341
commit
d6af58f572
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=98865
@ -167,8 +167,8 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
const u_char *cp;
|
||||
int n;
|
||||
const u_char *eom, *erdata;
|
||||
char *bp, **ap, **hap;
|
||||
int type, class, buflen, ancount, qdcount;
|
||||
char *bp, *ep, **ap, **hap;
|
||||
int type, class, ancount, qdcount;
|
||||
int haveanswer, had_error;
|
||||
int toobig = 0;
|
||||
char tbuf[MAXDNAME];
|
||||
@ -197,14 +197,14 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
ancount = ntohs(hp->ancount);
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
bp = hostbuf;
|
||||
buflen = sizeof hostbuf;
|
||||
ep = hostbuf + sizeof hostbuf;
|
||||
cp = answer->buf;
|
||||
BOUNDED_INCR(HFIXEDSZ);
|
||||
if (qdcount != 1) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
@ -222,7 +222,6 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
}
|
||||
host.h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
/* The qname can be abbreviated, but h_name is now absolute. */
|
||||
qname = host.h_name;
|
||||
}
|
||||
@ -236,7 +235,7 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
had_error = 0;
|
||||
_dns_ttl_ = -1;
|
||||
while (ancount-- > 0 && cp < eom && !had_error) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
had_error++;
|
||||
continue;
|
||||
@ -280,17 +279,15 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
continue;
|
||||
}
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN) {
|
||||
if (n > ep - bp || n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
strcpy(bp, tbuf);
|
||||
host.h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (qtype == T_PTR && type == T_CNAME) {
|
||||
@ -306,14 +303,13 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
}
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN) {
|
||||
if (n > ep - bp || n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
strcpy(bp, tbuf);
|
||||
tname = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (type != qtype) {
|
||||
@ -333,7 +329,7 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !res_hnok(bp)) {
|
||||
had_error++;
|
||||
break;
|
||||
@ -357,7 +353,6 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
@ -369,8 +364,7 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
_map_v4v6_hostent(&host, &bp, &buflen);
|
||||
_map_v4v6_hostent(&host, &bp, &ep);
|
||||
}
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
@ -393,13 +387,12 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
host.h_name = bp;
|
||||
nn = strlen(bp) + 1; /* for the \0 */
|
||||
bp += nn;
|
||||
buflen -= nn;
|
||||
}
|
||||
|
||||
buflen -= sizeof(align) - ((u_long)bp % sizeof(align));
|
||||
bp += sizeof(align) - ((u_long)bp % sizeof(align));
|
||||
|
||||
if (bp + n >= &hostbuf[sizeof hostbuf]) {
|
||||
if (bp + n >= ep) {
|
||||
dprintf("size (%d) too big\n", n);
|
||||
had_error++;
|
||||
continue;
|
||||
@ -413,7 +406,6 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
}
|
||||
bcopy(cp, *hap++ = bp, n);
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
@ -443,15 +435,14 @@ gethostanswer(answer, anslen, qname, qtype)
|
||||
# endif /*RESOLVSORT*/
|
||||
if (!host.h_name) {
|
||||
n = strlen(qname) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN)
|
||||
if (n > ep - bp || n >= MAXHOSTNAMELEN)
|
||||
goto no_recovery;
|
||||
strcpy(bp, qname);
|
||||
host.h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
if (_res.options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(&host, &bp, &buflen);
|
||||
_map_v4v6_hostent(&host, &bp, &ep);
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
}
|
||||
@ -489,7 +480,7 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
int af;
|
||||
querybuf buf;
|
||||
const char *cp;
|
||||
char *bp;
|
||||
char *bp, *ep;
|
||||
int n, size, type, len;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
@ -548,7 +539,7 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
strncpy(hostbuf, name, MAXDNAME);
|
||||
hostbuf[MAXDNAME] = '\0';
|
||||
bp = hostbuf + MAXDNAME;
|
||||
len = sizeof hostbuf - MAXDNAME;
|
||||
ep = hostbuf + sizeof hostbuf;
|
||||
host.h_name = hostbuf;
|
||||
host.h_aliases = host_aliases;
|
||||
host_aliases[0] = NULL;
|
||||
@ -556,7 +547,7 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
h_addr_ptrs[1] = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
if (_res.options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(&host, &bp, &len);
|
||||
_map_v4v6_hostent(&host, &bp, &ep);
|
||||
h_errno = NETDB_SUCCESS;
|
||||
*(struct hostent **)rval = &host;
|
||||
return NS_SUCCESS;
|
||||
|
@ -115,9 +115,9 @@ getnetanswer(answer, anslen, net_i)
|
||||
u_char *cp;
|
||||
int n;
|
||||
u_char *eom;
|
||||
int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
|
||||
int type, class, ancount, qdcount, haveanswer, i, nchar;
|
||||
char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
|
||||
char *in, *st, *pauxt, *bp, **ap;
|
||||
char *in, *st, *pauxt, *bp, *ep, **ap;
|
||||
char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
|
||||
static struct netent net_entry;
|
||||
static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
|
||||
@ -141,7 +141,6 @@ static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
|
||||
ancount = ntohs(hp->ancount); /* #/records in the answer section */
|
||||
qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
|
||||
bp = netbuf;
|
||||
buflen = sizeof(netbuf);
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (!qdcount) {
|
||||
if (hp->aa)
|
||||
@ -157,7 +156,7 @@ static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
|
||||
net_entry.n_aliases = net_aliases;
|
||||
haveanswer = 0;
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !res_dnok(bp))
|
||||
break;
|
||||
cp += n;
|
||||
@ -169,7 +168,7 @@ static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
|
||||
cp += INT32SZ; /* TTL */
|
||||
GETSHORT(n, cp);
|
||||
if (class == C_IN && type == T_PTR) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !res_hnok(bp)) {
|
||||
cp += n;
|
||||
return (NULL);
|
||||
|
@ -99,10 +99,10 @@ _map_v4v6_address(src, dst)
|
||||
}
|
||||
|
||||
void
|
||||
_map_v4v6_hostent(hp, bpp, lenp)
|
||||
_map_v4v6_hostent(hp, bpp, epp)
|
||||
struct hostent *hp;
|
||||
char **bpp;
|
||||
int *lenp;
|
||||
char **epp;
|
||||
{
|
||||
char **ap;
|
||||
|
||||
@ -113,16 +113,14 @@ _map_v4v6_hostent(hp, bpp, lenp)
|
||||
for (ap = hp->h_addr_list; *ap; ap++) {
|
||||
int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
|
||||
|
||||
if (*lenp < (i + IN6ADDRSZ)) {
|
||||
if (*epp - *bpp < (i + IN6ADDRSZ)) {
|
||||
/* Out of memory. Truncate address list here. XXX */
|
||||
*ap = NULL;
|
||||
return;
|
||||
}
|
||||
*bpp += i;
|
||||
*lenp -= i;
|
||||
_map_v4v6_address(*ap, *bpp);
|
||||
*ap = *bpp;
|
||||
*bpp += IN6ADDRSZ;
|
||||
*lenp -= IN6ADDRSZ;
|
||||
}
|
||||
}
|
||||
|
@ -997,8 +997,8 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
const u_char *cp;
|
||||
int n;
|
||||
const u_char *eom, *erdata;
|
||||
char *bp, **ap, **hap, *obp;
|
||||
int type, class, buflen, ancount, qdcount;
|
||||
char *bp, *ep, **ap, **hap;
|
||||
int type, class, ancount, qdcount;
|
||||
int haveanswer, had_error;
|
||||
char tbuf[MAXDNAME];
|
||||
const char *tname;
|
||||
@ -1063,14 +1063,14 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
ancount = ntohs(hp->ancount);
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
bp = hostbuf;
|
||||
buflen = sizeof hostbuf;
|
||||
ep = hostbuf + sizeof hostbuf;
|
||||
cp = answer->buf;
|
||||
BOUNDED_INCR(HFIXEDSZ);
|
||||
if (qdcount != 1) {
|
||||
*errp = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
*errp = NO_RECOVERY;
|
||||
return (NULL);
|
||||
@ -1088,7 +1088,6 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
}
|
||||
template->h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
/* The qname can be abbreviated, but h_name is now absolute. */
|
||||
qname = template->h_name;
|
||||
}
|
||||
@ -1101,7 +1100,7 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
haveanswer = 0;
|
||||
had_error = 0;
|
||||
while (ancount-- > 0 && cp < eom && !had_error) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
DNS_FATAL(n >= 0);
|
||||
DNS_FATAL((*name_ok)(bp));
|
||||
cp += n; /* name */
|
||||
@ -1131,15 +1130,13 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
DNS_FATAL(n < MAXHOSTNAMELEN);
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
DNS_FATAL(n <= buflen);
|
||||
DNS_FATAL(n <= ep - bp);
|
||||
DNS_FATAL(n < MAXHOSTNAMELEN);
|
||||
strcpy(bp, tbuf);
|
||||
template->h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (qtype == T_PTR && type == T_CNAME) {
|
||||
@ -1155,21 +1152,20 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
}
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN) {
|
||||
if (n > ep - bp || n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
strcpy(bp, tbuf);
|
||||
tname = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
DNS_ASSERT(type == qtype);
|
||||
switch (type) {
|
||||
case T_PTR:
|
||||
DNS_ASSERT(strcasecmp(tname, bp) == 0);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
DNS_FATAL(n >= 0);
|
||||
DNS_FATAL(res_hnok(bp));
|
||||
#if MULTI_PTRS_ARE_ALIASES
|
||||
@ -1191,7 +1187,6 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
@ -1209,13 +1204,12 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
template->h_name = bp;
|
||||
nn = strlen(bp) + 1; /* for the \0 */
|
||||
bp += nn;
|
||||
buflen -= nn;
|
||||
}
|
||||
obp = bp; /* ALIGN rounds up */
|
||||
bp = (char *)ALIGN(bp);
|
||||
buflen -= (bp - obp);
|
||||
|
||||
DNS_FATAL(bp + n < &hostbuf[sizeof hostbuf]);
|
||||
DNS_FATAL(bp + n < ep);
|
||||
DNS_ASSERT(hap < &h_addr_ptrs[MAXADDRS-1]);
|
||||
#ifdef FILTER_V4MAPPED
|
||||
if (type == T_AAAA) {
|
||||
@ -1226,7 +1220,6 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
#endif
|
||||
bcopy(cp, *hap++ = bp, n);
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
*errp = NO_RECOVERY;
|
||||
@ -1244,12 +1237,11 @@ getanswer(answer, anslen, qname, qtype, template, errp)
|
||||
*hap = NULL;
|
||||
if (!template->h_name) {
|
||||
n = strlen(qname) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN)
|
||||
if (n > ep - bp || n >= MAXHOSTNAMELEN)
|
||||
goto no_recovery;
|
||||
strcpy(bp, qname);
|
||||
template->h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
*errp = NETDB_SUCCESS;
|
||||
return (template);
|
||||
|
Loading…
Reference in New Issue
Block a user