1338. [bug] libbind: Remote buffer overrun.
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
||||
1338. [bug] libbind: Remote buffer overrun.
|
||||
|
||||
1337. [port] libbind: TrueUNIX 5.1 does not like __align as a
|
||||
element name.
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
/* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_ho.c,v 1.9 2002/06/28 05:00:55 marka Exp $";
|
||||
static const char rcsid[] = "$Id: dns_ho.c,v 1.10 2002/06/28 06:06:23 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports. */
|
||||
@@ -161,7 +161,7 @@ static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
static void map_v4v6_hostent(struct hostent *hp, char **bp,
|
||||
int *len);
|
||||
char *ep);
|
||||
static void addrsort(res_state, char **, int);
|
||||
static struct hostent * gethostans(struct irs_ho *this,
|
||||
const u_char *ansbuf, int anslen,
|
||||
@@ -1079,7 +1079,7 @@ gethostans(struct irs_ho *this,
|
||||
struct addrinfo **ret_aip, const struct addrinfo *pai)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int type, class, buflen, ancount, qdcount, n, haveanswer, had_error;
|
||||
int type, class, ancount, qdcount, n, haveanswer, had_error;
|
||||
int error = NETDB_SUCCESS, arcount;
|
||||
int (*name_ok)(const char *);
|
||||
const HEADER *hp;
|
||||
@@ -1088,7 +1088,7 @@ gethostans(struct irs_ho *this,
|
||||
const u_char *cp;
|
||||
const char *tname;
|
||||
const char *hname;
|
||||
char *bp, **ap, **hap;
|
||||
char *bp, *ep, **ap, **hap;
|
||||
char tbuf[MAXDNAME+1];
|
||||
struct addrinfo sentinel, *cur, ai;
|
||||
const u_char *arp = NULL;
|
||||
@@ -1131,13 +1131,13 @@ gethostans(struct irs_ho *this,
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
arcount = ntohs(hp->arcount);
|
||||
bp = pvt->hostbuf;
|
||||
buflen = sizeof pvt->hostbuf;
|
||||
ep = pvt->hostbuf + sizeof(pvt->hostbuf);
|
||||
cp = ansbuf + HFIXEDSZ;
|
||||
if (qdcount != 1) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
n = dn_expand(ansbuf, eom, cp, bp, buflen);
|
||||
n = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
@@ -1161,7 +1161,6 @@ gethostans(struct irs_ho *this,
|
||||
pvt->host.h_name = bp;
|
||||
hname = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
/* The qname can be abbreviated, but hname is now absolute. */
|
||||
qname = pvt->host.h_name;
|
||||
}
|
||||
@@ -1174,7 +1173,7 @@ gethostans(struct irs_ho *this,
|
||||
haveanswer = 0;
|
||||
had_error = 0;
|
||||
while (ancount-- > 0 && cp < eom && !had_error) {
|
||||
n = dn_expand(ansbuf, eom, cp, bp, buflen);
|
||||
n = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) {
|
||||
had_error++;
|
||||
continue;
|
||||
@@ -1207,10 +1206,9 @@ gethostans(struct irs_ho *this,
|
||||
*ap++ = bp;
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
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;
|
||||
}
|
||||
@@ -1218,7 +1216,6 @@ gethostans(struct irs_ho *this,
|
||||
pvt->host.h_name = bp;
|
||||
hname = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (type == ns_t_dname) {
|
||||
@@ -1254,7 +1251,7 @@ gethostans(struct irs_ho *this,
|
||||
cp += n;
|
||||
|
||||
n = strlen(t) + 1; /* for the \0 */
|
||||
if (n > buflen) {
|
||||
if (n > (ep - bp)) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
@@ -1264,7 +1261,6 @@ gethostans(struct irs_ho *this,
|
||||
else
|
||||
hname = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -1290,14 +1286,13 @@ gethostans(struct irs_ho *this,
|
||||
}
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
if (n > buflen) {
|
||||
if (n > (ep - bp)) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
strcpy(bp, tbuf);
|
||||
tname = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (qtype == T_ANY) {
|
||||
@@ -1321,7 +1316,7 @@ gethostans(struct irs_ho *this,
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
n = dn_expand(ansbuf, eor, cp, bp, buflen);
|
||||
n = dn_expand(ansbuf, eor, cp, bp, ep - bp);
|
||||
if (n < 0 || !maybe_hnok(pvt->res, bp) ||
|
||||
n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
@@ -1339,7 +1334,6 @@ gethostans(struct irs_ho *this,
|
||||
if (n != -1) {
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
break;
|
||||
case ns_t_a6: {
|
||||
@@ -1439,7 +1433,6 @@ gethostans(struct irs_ho *this,
|
||||
pvt->host.h_name = bp;
|
||||
hname = bp;
|
||||
bp += nn;
|
||||
buflen -= nn;
|
||||
}
|
||||
/* Ensure alignment. */
|
||||
bp = (char *)(((u_long)bp + (sizeof(align) - 1)) &
|
||||
@@ -1493,15 +1486,14 @@ gethostans(struct irs_ho *this,
|
||||
haveanswer);
|
||||
if (pvt->host.h_name == NULL) {
|
||||
n = strlen(qname) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN)
|
||||
if (n > (ep - bp) || n >= MAXHOSTNAMELEN)
|
||||
goto no_recovery;
|
||||
strcpy(bp, qname);
|
||||
pvt->host.h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
if (pvt->res->options & RES_USE_INET6)
|
||||
map_v4v6_hostent(&pvt->host, &bp, &buflen);
|
||||
map_v4v6_hostent(&pvt->host, &bp, ep);
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (&pvt->host);
|
||||
} else {
|
||||
@@ -1575,7 +1567,7 @@ add_hostent(struct pvt *pvt, char *bp, char **hap, struct addrinfo *ai)
|
||||
}
|
||||
|
||||
static void
|
||||
map_v4v6_hostent(struct hostent *hp, char **bpp, int *lenp) {
|
||||
map_v4v6_hostent(struct hostent *hp, char **bpp, char *ep) {
|
||||
char **ap;
|
||||
|
||||
if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
|
||||
@@ -1588,17 +1580,15 @@ map_v4v6_hostent(struct hostent *hp, char **bpp, int *lenp) {
|
||||
if (i != 0)
|
||||
i = sizeof(align) - i;
|
||||
|
||||
if (*lenp < (i + IN6ADDRSZ)) {
|
||||
if ((ep - *bpp) < (i + IN6ADDRSZ)) {
|
||||
/* Out of memory. Truncate address list here. */
|
||||
*ap = NULL;
|
||||
return;
|
||||
}
|
||||
*bpp += i;
|
||||
*lenp -= i;
|
||||
map_v4v6_address(*ap, *bpp);
|
||||
*ap = *bpp;
|
||||
*bpp += IN6ADDRSZ;
|
||||
*lenp -= IN6ADDRSZ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_nw.c,v 1.5 2002/02/27 04:03:11 marka Exp $";
|
||||
static const char rcsid[] = "$Id: dns_nw.c,v 1.6 2002/06/28 06:06:24 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports. */
|
||||
@@ -299,8 +299,8 @@ get1101answer(struct irs_nw *this,
|
||||
int af, const char *name, const u_char *addr, int addrlen)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int type, class, buflen, ancount, qdcount, haveanswer;
|
||||
char *bp, **ap;
|
||||
int type, class, ancount, qdcount, haveanswer;
|
||||
char *bp, *ep, **ap;
|
||||
u_char *cp, *eom;
|
||||
HEADER *hp;
|
||||
|
||||
@@ -332,7 +332,7 @@ get1101answer(struct irs_nw *this,
|
||||
|
||||
/* Prepare a return structure. */
|
||||
bp = pvt->buf;
|
||||
buflen = sizeof pvt->buf;
|
||||
ep = pvt->buf + sizeof(pvt->buf);
|
||||
pvt->net.n_name = NULL;
|
||||
pvt->net.n_aliases = pvt->ali;
|
||||
pvt->net.n_addrtype = af;
|
||||
@@ -345,20 +345,19 @@ get1101answer(struct irs_nw *this,
|
||||
if (name != NULL) {
|
||||
int n = strlen(name) + 1;
|
||||
|
||||
if (n > buflen) {
|
||||
if (n > (ep - bp)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
pvt->net.n_name = strcpy(bp, name);
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
break;
|
||||
case by_addr:
|
||||
if (addr != NULL && addrlen != 0) {
|
||||
int n = addrlen / 8 + ((addrlen % 8) != 0);
|
||||
|
||||
if (INADDRSZ > buflen) {
|
||||
if (INADDRSZ > (ep - bp)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -366,7 +365,6 @@ get1101answer(struct irs_nw *this,
|
||||
memcpy(bp, addr, n);
|
||||
pvt->net.n_addr = bp;
|
||||
bp += INADDRSZ;
|
||||
buflen -= INADDRSZ;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -377,7 +375,7 @@ get1101answer(struct irs_nw *this,
|
||||
ap = pvt->ali;
|
||||
haveanswer = 0;
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
int n = dn_expand(ansbuf, eom, cp, bp, buflen);
|
||||
int n = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
|
||||
cp += n; /* Owner */
|
||||
if (n < 0 || !maybe_dnok(pvt->res, bp) ||
|
||||
@@ -392,7 +390,7 @@ get1101answer(struct irs_nw *this,
|
||||
if (class == C_IN && type == T_PTR) {
|
||||
int nn;
|
||||
|
||||
nn = dn_expand(ansbuf, eom, cp, bp, buflen);
|
||||
nn = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
if (nn < 0 || !maybe_hnok(pvt->res, bp) || nn != n) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
@@ -408,7 +406,6 @@ get1101answer(struct irs_nw *this,
|
||||
*ap++ = bp;
|
||||
nn = strlen(bp) + 1;
|
||||
bp += nn;
|
||||
buflen -= nn;
|
||||
haveanswer++;
|
||||
break;
|
||||
}
|
||||
@@ -419,7 +416,7 @@ get1101answer(struct irs_nw *this,
|
||||
sscanf(bp, "%u.%u.%u.%u.in-addr.arpa",
|
||||
&b1, &b2, &b3, &b4) != 4)
|
||||
break;
|
||||
if (buflen < INADDRSZ) {
|
||||
if ((ep - bp) < INADDRSZ) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -428,7 +425,6 @@ get1101answer(struct irs_nw *this,
|
||||
*bp++ = b3;
|
||||
*bp++ = b2;
|
||||
*bp++ = b1;
|
||||
buflen -= INADDRSZ;
|
||||
pvt->net.n_length = INADDRSZ * 8;
|
||||
haveanswer++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user