Index: bind8/src/CHANGES diff -c bind8/src/CHANGES:8.798.2.71 bind8/src/CHANGES:8.798.2.71.2.3 *** bind8/src/CHANGES:8.798.2.71 Thu Sep 27 23:41:55 2001 --- bind8/src/CHANGES Wed Jun 26 21:19:29 2002 *************** *** 1,3 **** --- 1,10 ---- + + --- 8.2.6-REL released --- (Wed Jun 26 21:15:43 PDT 2002) + + 1301. [func] log attempts to exploit #1300. + + 1300. [bug] Remote buffer overrun. + --- 8.2.5-REL released --- (Thu Sep 27 23:41:08 PDT 2001) 1272. [bug] "rndc trace 0" should behave like "rndc notrace". Index: bind8/src/README diff -c bind8/src/README:8.44.2.2 bind8/src/README:8.44.2.2.2.1 *** bind8/src/README:8.44.2.2 Sun Jun 17 23:22:03 2001 --- bind8/src/README Wed Jun 26 21:19:30 2002 *************** *** 10,15 **** --- 10,19 ---- Note that BIND 8 is in "end-of-life", having been replaced by BIND 9. See http://www.isc.org/ for more details. + BIND 8.2.6 Highlights + Security Fix in libbind. All applications linked against libbind + need to relinked. + BIND 8.2.5 Highlights Bug Fixes. Index: bind8/src/Version diff -c bind8/src/Version:8.65.2.6 bind8/src/Version:8.65.2.6.2.1 *** bind8/src/Version:8.65.2.6 Tue Sep 4 20:13:34 2001 --- bind8/src/Version Wed Jun 26 21:19:32 2002 *************** *** 1 **** ! 8.2.5-REL --- 1 ---- ! 8.2.6-REL Index: bind8/src/bin/named/ns_resp.c diff -c bind8/src/bin/named/ns_resp.c:8.152.2.4 bind8/src/bin/named/ns_resp.c:8.152.2.4.2.1 *** bind8/src/bin/named/ns_resp.c:8.152.2.4 Mon Aug 20 00:18:09 2001 --- bind8/src/bin/named/ns_resp.c Wed Jun 26 21:15:00 2002 *************** *** 306,311 **** --- 306,312 ---- u_char sig[TSIG_SIG_SIZE]; time_t tsig_time; DST_KEY *key; + int expect_cname; nameserIncr(from.sin_addr, nssRcvdR); nsp[0] = NULL; *************** *** 916,921 **** --- 917,923 ---- } else flushset = NULL; + expect_cname = 1; for (i = 0; i < count; i++) { struct databuf *dp; int type; *************** *** 947,952 **** --- 949,967 ---- type = dp->d_type; if (i < ancount) { /* Answer section. */ + /* + * Check for attempts to overflow the buffer in + * getnameanswer. + */ + if (type == ns_t_cname && !expect_cname) { + ns_warning(ns_log_security, + "late CNAME in answer section for %s %s from %s", + *qname ? qname : ".", p_type(qtype), + sin_ntoa(from)); + + } else if (type != ns_t_cname && type != ns_t_dname && + type != ns_t_sig) + expect_cname = 0; if (externalcname || ns_samename(name, aname) != 1) { if (!externalcname) ns_info(ns_log_resp_checks, Index: bind8/src/lib/irs/dns_ho.c diff -c bind8/src/lib/irs/dns_ho.c:1.28.2.1 bind8/src/lib/irs/dns_ho.c:1.28.2.1.2.2 *** bind8/src/lib/irs/dns_ho.c:1.28.2.1 Sun Jul 1 18:27:16 2001 --- bind8/src/lib/irs/dns_ho.c Wed Jun 26 21:15:02 2002 *************** *** 74,79 **** --- 74,80 ---- #include #include #include + #include #include #include *************** *** 139,145 **** void (*free_res)(void *)); static void map_v4v6_hostent(struct hostent *hp, char **bp, ! int *len); static void addrsort(res_state, char **, int); static struct hostent * gethostans(struct irs_ho *this, const u_char *ansbuf, int anslen, --- 140,146 ---- void (*free_res)(void *)); static void map_v4v6_hostent(struct hostent *hp, char **bp, ! char *ep); static void addrsort(res_state, char **, int); static struct hostent * gethostans(struct irs_ho *this, const u_char *ansbuf, int anslen, *************** *** 385,397 **** int af, int size) { struct pvt *pvt = (struct pvt *)this->private; ! int type, class, buflen, ancount, qdcount, n, haveanswer, had_error; int (*name_ok)(const char *); const HEADER *hp; const u_char *eom; const u_char *cp; const char *tname, **tap; ! char *bp, **ap, **hap; char tbuf[MAXDNAME+1]; tname = qname; --- 386,398 ---- int af, int size) { struct pvt *pvt = (struct pvt *)this->private; ! int type, class, ancount, qdcount, n, haveanswer, had_error; int (*name_ok)(const char *); const HEADER *hp; const u_char *eom; const u_char *cp; const char *tname, **tap; ! char *bp, *ep, **ap, **hap; char tbuf[MAXDNAME+1]; tname = qname; *************** *** 423,435 **** ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = pvt->hostbuf; ! buflen = 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); if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); --- 424,436 ---- ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = 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, ep - bp); if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); *************** *** 451,457 **** } pvt->host.h_name = bp; bp += n; - buflen -= n; /* The qname can be abbreviated, but h_name is now absolute. */ qname = pvt->host.h_name; } --- 452,457 ---- *************** *** 464,470 **** haveanswer = 0; had_error = 0; while (ancount-- > 0 && cp < eom && !had_error) { ! n = dn_expand(ansbuf, eom, cp, bp, buflen); if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) { had_error++; continue; --- 464,470 ---- haveanswer = 0; had_error = 0; while (ancount-- > 0 && cp < eom && !had_error) { ! n = dn_expand(ansbuf, eom, cp, bp, ep - bp); if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) { had_error++; continue; *************** *** 483,488 **** --- 483,497 ---- continue; } if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { + if (haveanswer) { + int level = LOG_CRIT; + #ifdef LOG_SECURITY + level |= LOG_SECURITY; + #endif + syslog(level, + "gethostans: possible attempt to exploit buffer overflow while looking up %s", + *qname ? qname : "."); + } if (ap >= &pvt->host_aliases[MAXALIASES-1]) continue; n = dn_expand(ansbuf, eom, cp, tbuf, sizeof tbuf); *************** *** 495,511 **** *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) { had_error++; continue; } strcpy(bp, tbuf); pvt->host.h_name = bp; bp += n; - buflen -= n; continue; } if (qtype == T_PTR && type == T_CNAME) { --- 504,518 ---- *ap++ = bp; n = strlen(bp) + 1; /* for the \0 */ bp += n; /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ ! if (n > (ep - bp) || n > MAXHOSTNAMELEN) { had_error++; continue; } strcpy(bp, tbuf); pvt->host.h_name = bp; bp += n; continue; } if (qtype == T_PTR && type == T_CNAME) { *************** *** 517,530 **** cp += n; /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ ! if (n > buflen) { had_error++; continue; } strcpy(bp, tbuf); tname = bp; bp += n; - buflen -= n; continue; } if (type != qtype) { --- 524,536 ---- cp += n; /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ ! if (n > (ep - bp)) { had_error++; continue; } strcpy(bp, tbuf); tname = bp; bp += n; continue; } if (type != qtype) { *************** *** 537,543 **** cp += n; continue; } ! n = dn_expand(ansbuf, eom, cp, bp, buflen); if (n < 0 || !maybe_hnok(pvt->res, bp) || n >= MAXHOSTNAMELEN) { had_error++; --- 543,549 ---- cp += n; continue; } ! n = dn_expand(ansbuf, eom, cp, bp, ep - bp); if (n < 0 || !maybe_hnok(pvt->res, bp) || n >= MAXHOSTNAMELEN) { had_error++; *************** *** 553,559 **** if (n != -1) { n = strlen(bp) + 1; /* for the \0 */ bp += n; - buflen -= n; } break; case T_A: --- 559,564 ---- *************** *** 577,583 **** } pvt->host.h_name = bp; bp += nn; - buflen -= nn; } /* Ensure alignment. */ bp += sizeof(align) - ((u_long)bp % sizeof(align)); --- 582,587 ---- *************** *** 619,633 **** addrsort(pvt->res, pvt->h_addr_ptrs, haveanswer); if (!pvt->host.h_name) { n = strlen(qname) + 1; /* for the \0 */ ! if (n > buflen || 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); RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); return (&pvt->host); } --- 623,636 ---- addrsort(pvt->res, pvt->h_addr_ptrs, haveanswer); if (!pvt->host.h_name) { n = strlen(qname) + 1; /* for the \0 */ ! if (n > (ep - bp) || n >= MAXHOSTNAMELEN) goto no_recovery; strcpy(bp, qname); pvt->host.h_name = bp; bp += n; } if (pvt->res->options & RES_USE_INET6) ! map_v4v6_hostent(&pvt->host, &bp, ep); RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); return (&pvt->host); } *************** *** 637,643 **** } static void ! map_v4v6_hostent(struct hostent *hp, char **bpp, int *lenp) { char **ap; if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) --- 640,646 ---- } static void ! map_v4v6_hostent(struct hostent *hp, char **bpp, char *ep) { char **ap; if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) *************** *** 647,663 **** for (ap = hp->h_addr_list; *ap; ap++) { int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); ! if (*lenp < (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; } } --- 650,664 ---- for (ap = hp->h_addr_list; *ap; ap++) { int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); ! if ((ep - *bpp) < (i + IN6ADDRSZ)) { /* Out of memory. Truncate address list here. */ *ap = NULL; return; } *bpp += i; map_v4v6_address(*ap, *bpp); *ap = *bpp; *bpp += IN6ADDRSZ; } } Index: bind8/src/lib/irs/dns_nw.c diff -c bind8/src/lib/irs/dns_nw.c:1.19 bind8/src/lib/irs/dns_nw.c:1.19.6.1 *** bind8/src/lib/irs/dns_nw.c:1.19 Fri Oct 15 12:49:10 1999 --- bind8/src/lib/irs/dns_nw.c Wed Jun 26 19:45:45 2002 *************** *** 277,284 **** 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; u_char *cp, *eom; HEADER *hp; --- 277,284 ---- int af, const char *name, const u_char *addr, int addrlen) { struct pvt *pvt = (struct pvt *)this->private; ! int type, class, ancount, qdcount, haveanswer; ! char *bp, *ep, **ap; u_char *cp, *eom; HEADER *hp; *************** *** 310,316 **** /* Prepare a return structure. */ bp = pvt->buf; ! buflen = sizeof pvt->buf; pvt->net.n_name = NULL; pvt->net.n_aliases = pvt->ali; pvt->net.n_addrtype = af; --- 310,316 ---- /* Prepare a return structure. */ bp = pvt->buf; ! ep = pvt->buf + sizeof(pvt->buf); pvt->net.n_name = NULL; pvt->net.n_aliases = pvt->ali; pvt->net.n_addrtype = af; *************** *** 323,342 **** if (name != NULL) { int n = strlen(name) + 1; ! if (n > buflen) { 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) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } --- 323,341 ---- if (name != NULL) { int n = strlen(name) + 1; ! if (n > (ep - bp)) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } pvt->net.n_name = strcpy(bp, name); bp += n; } break; case by_addr: if (addr != NULL && addrlen != 0) { int n = addrlen / 8 + ((addrlen % 8) != 0); ! if (INADDRSZ > (ep - bp)) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } *************** *** 344,350 **** memcpy(bp, addr, n); pvt->net.n_addr = bp; bp += INADDRSZ; - buflen -= INADDRSZ; } break; default: --- 343,348 ---- *************** *** 355,361 **** ap = pvt->ali; haveanswer = 0; while (--ancount >= 0 && cp < eom) { ! int n = dn_expand(ansbuf, eom, cp, bp, buflen); cp += n; /* Owner */ if (n < 0 || !maybe_dnok(pvt->res, bp) || --- 353,359 ---- ap = pvt->ali; haveanswer = 0; while (--ancount >= 0 && cp < eom) { ! int n = dn_expand(ansbuf, eom, cp, bp, ep - bp); cp += n; /* Owner */ if (n < 0 || !maybe_dnok(pvt->res, bp) || *************** *** 370,376 **** if (class == C_IN && type == T_PTR) { int nn; ! nn = dn_expand(ansbuf, eom, cp, bp, buflen); if (nn < 0 || !maybe_hnok(pvt->res, bp) || nn != n) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); --- 368,374 ---- if (class == C_IN && type == T_PTR) { int nn; ! 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); *************** *** 386,392 **** *ap++ = bp; nn = strlen(bp) + 1; bp += nn; - buflen -= nn; haveanswer++; break; } --- 384,389 ---- *************** *** 397,403 **** sscanf(bp, "%u.%u.%u.%u.in-addr.arpa", &b1, &b2, &b3, &b4) != 4) break; ! if (buflen < INADDRSZ) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } --- 394,400 ---- sscanf(bp, "%u.%u.%u.%u.in-addr.arpa", &b1, &b2, &b3, &b4) != 4) break; ! if ((ep - bp) < INADDRSZ) { RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } *************** *** 406,412 **** *bp++ = b3; *bp++ = b2; *bp++ = b1; - buflen -= INADDRSZ; pvt->net.n_length = INADDRSZ * 8; haveanswer++; } --- 403,408 ----