Index: bind4/CHANGES diff -u bind4/CHANGES:8.66 bind4/CHANGES:8.71 --- bind4/CHANGES:8.66 Wed Jun 26 07:52:39 2002 +++ bind4/CHANGES Thu Aug 8 02:50:26 2002 @@ -1,5 +1,13 @@ $Id$ + --- 4.9.10-REL released --- + +821. [bug] read buffer overflows. + +820. [port] __printf0like required for test build under FreeBSD. + +819. [cleanup] res_mkquery.c: kill buflen manipulation. + --- 4.9.9-REL released --- 818. [bug] remote buffer overrun. Index: bind4/Makefile diff -u bind4/Makefile:8.56 bind4/Makefile:8.57 --- bind4/Makefile:8.56 Wed Jun 26 07:52:41 2002 +++ bind4/Makefile Thu Aug 8 02:50:26 2002 @@ -52,7 +52,7 @@ ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ## SOFTWARE. -VER = 4.9.9-REL +VER = 4.9.10-REL SHELL = /bin/sh MAKE = make DESTDIR = Index: bind4/README diff -u bind4/README:8.10 bind4/README:8.11 --- bind4/README:8.10 Wed Jun 26 07:52:40 2002 +++ bind4/README Thu Aug 8 13:20:30 2002 @@ -4,7 +4,7 @@ The official version of ISC BIND is now 9.1.0, or failing that, 8.2.3. -This is ISC BIND 4.9.9, hoped to be the last of 4.*, which we are releasing +This is ISC BIND 4.9.10, hoped to be the last of 4.*, which we are releasing since it has an important security bug fixed. Other less important security bugs in BIND4 remain *unfixed*. You should not be running it. You have been warned. Index: bind4/compat/include/sys/cdefs.h diff -u bind4/compat/include/sys/cdefs.h:8.6 bind4/compat/include/sys/cdefs.h:8.7 --- bind4/compat/include/sys/cdefs.h:8.6 Sat Dec 16 22:29:21 2000 +++ bind4/compat/include/sys/cdefs.h Fri Jun 28 06:55:06 2002 @@ -130,6 +130,7 @@ #define __pure #define __pure2 __attribute__((const)) #define __printflike(x, y) +#define __printf0like(x, y) #define __scanflike(x, y) #endif Index: bind4/res/gethnamaddr.c diff -u bind4/res/gethnamaddr.c:8.24 bind4/res/gethnamaddr.c:8.27 --- bind4/res/gethnamaddr.c:8.24 Wed Jun 26 07:46:29 2002 +++ bind4/res/gethnamaddr.c Thu Aug 8 23:02:55 2002 @@ -117,11 +117,7 @@ static void addrsort __P((char **, int)); #endif -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (64*1024) typedef union { HEADER hdr; @@ -477,11 +473,12 @@ const char *name; int af; { - querybuf buf; + querybuf *buf; register const char *cp; char *bp, *ep; int n, size, type; extern struct hostent *_gethtbyname2(); + struct hostent *hp; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; @@ -582,13 +579,22 @@ break; } - if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { + buf = malloc(sizeof(*buf)); + if (buf == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + n = res_search(name, C_IN, type, buf->buf, sizeof(buf->buf)); + if (n < 0) { + free(buf); dprintf("res_search failed (%d)\n", n); if (errno == ECONNREFUSED) return (_gethtbyname2(name, af)); return (NULL); } - return (getanswer(&buf, n, name, type)); + hp = getanswer(buf, n, name, type); + free(buf); + return (hp); } struct hostent * @@ -600,7 +606,7 @@ static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; int n, size; - querybuf buf; + querybuf *buf; register struct hostent *hp; char qbuf[MAXDNAME+1], *qp; #ifdef SUNSECURITY @@ -615,6 +621,7 @@ h_errno = NETDB_INTERNAL; return (NULL); } + if (af == AF_INET6 && len == IN6ADDRSZ && (!bcmp(uaddr, mapped, sizeof mapped) || !bcmp(uaddr, tunnelled, sizeof tunnelled))) { @@ -661,14 +668,23 @@ default: abort(); } - n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + + buf = malloc(sizeof(*buf)); + if (buf == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof(buf->buf)); if (n < 0) { + free(buf); dprintf("res_query failed (%d)\n", n); if (errno == ECONNREFUSED) return (_gethtbyaddr(addr, len, af)); return (NULL); } - if (!(hp = getanswer(&buf, n, qbuf, T_PTR))) + hp = getanswer(buf, n, qbuf, T_PTR); + free(buf); + if (hp == NULL) return (NULL); /* h_errno was set by getanswer() */ #ifdef SUNSECURITY if (af == AF_INET) { Index: bind4/res/getnetnamadr.c diff -u bind4/res/getnetnamadr.c:8.9 bind4/res/getnetnamadr.c:8.11 --- bind4/res/getnetnamadr.c:8.9 Wed Jun 26 07:46:30 2002 +++ bind4/res/getnetnamadr.c Thu Aug 8 23:02:55 2002 @@ -64,6 +64,12 @@ extern int errno; #endif +#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) +# include +#else +# include "../conf/portability.h" +#endif + struct netent *_getnetbyaddr __P((long net, int type)); struct netent *_getnetbyname __P((const char *name)); @@ -71,11 +77,7 @@ #define BYNAME 1 #define MAXALIASES 35 -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (64*1024) typedef union { HEADER hdr; @@ -208,7 +210,7 @@ { unsigned int netbr[4]; int nn, anslen; - querybuf buf; + querybuf *buf; char qbuf[MAXDNAME]; unsigned long net2; struct netent *net_entry; @@ -234,8 +236,14 @@ netbr[1], netbr[0]); break; } - anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + buf = malloc(sizeof(*buf)); + if (buf == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + anslen = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof(buf->buf)); if (anslen < 0) { + free(buf); #ifdef DEBUG if (_res.options & RES_DEBUG) printf("res_query failed\n"); @@ -244,7 +252,8 @@ return (_getnetbyaddr(net, net_type)); return (NULL); } - net_entry = getnetanswer(&buf, anslen, BYADDR); + net_entry = getnetanswer(buf, anslen, BYADDR); + free(buf); if (net_entry) { unsigned u_net = net; /* maybe net should be unsigned ? */ @@ -262,7 +271,7 @@ register const char *net; { int anslen; - querybuf buf; + querybuf *buf; char qbuf[MAXDNAME]; struct netent *net_entry; @@ -271,8 +280,14 @@ return (NULL); } strcpy(&qbuf[0], net); - anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + buf = malloc(sizeof(*buf)); + if (buf == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + anslen = res_search(qbuf, C_IN, T_PTR, buf->buf, sizeof(buf->buf)); if (anslen < 0) { + free(buf); #ifdef DEBUG if (_res.options & RES_DEBUG) printf("res_query failed\n"); @@ -281,7 +296,8 @@ return (_getnetbyname(net)); return (_getnetbyname(net)); } - net_entry = getnetanswer(&buf, anslen, BYNAME); + net_entry = getnetanswer(buf, anslen, BYNAME); + free(buf); if (net_entry) return (net_entry); return (_getnetbyname(net)); Index: bind4/res/res_mkquery.c diff -u bind4/res/res_mkquery.c:8.5 bind4/res/res_mkquery.c:8.6 --- bind4/res/res_mkquery.c:8.5 Tue Aug 27 08:33:28 1996 +++ bind4/res/res_mkquery.c Fri Jun 28 06:49:55 2002 @@ -92,7 +92,7 @@ int buflen; /* size of buffer */ { register HEADER *hp; - register u_char *cp; + register u_char *cp, *ep; register int n; u_char *dnptrs[20], **dpp, **lastdnptr; @@ -117,7 +117,7 @@ hp->rd = (_res.options & RES_RECURSE) != 0; hp->rcode = NOERROR; cp = buf + HFIXEDSZ; - buflen -= HFIXEDSZ; + ep = buf + buflen; dpp = dnptrs; *dpp++ = buf; *dpp++ = NULL; @@ -128,12 +128,12 @@ switch (op) { case QUERY: /*FALLTHROUGH*/ case NS_NOTIFY_OP: - if ((buflen -= QFIXEDSZ) < 0) + if (ep - cp < QFIXEDSZ) return (-1); - if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs, lastdnptr); + if (n < 0) return (-1); cp += n; - buflen -= n; __putshort(type, cp); cp += INT16SZ; __putshort(class, cp); @@ -144,12 +144,13 @@ /* * Make an additional record for completion domain. */ - buflen -= RRFIXEDSZ; - n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); + if (ep - cp < RRFIXEDSZ) + return (-1); + n = dn_comp((char *)data, cp, ep - cp - RRFIXEDSZ, dnptrs, + lastdnptr); if (n < 0) return (-1); cp += n; - buflen -= n; __putshort(T_NULL, cp); cp += INT16SZ; __putshort(class, cp); @@ -165,7 +166,7 @@ /* * Initialize answer section */ - if (buflen < 1 + RRFIXEDSZ + datalen) + if (ep - cp < 1 + RRFIXEDSZ + datalen) return (-1); *cp++ = '\0'; /* no domain name */ __putshort(type, cp);