Index: bind4/CHANGES
diff -c bind4/CHANGES:8.64 bind4/CHANGES:8.66
*** bind4/CHANGES:8.64	Sat Jan 27 15:29:21 2001
--- bind4/CHANGES	Wed Jun 26 00:52:39 2002
***************
*** 1,5 ****
--- 1,9 ----
  $Id$
  
+ 	--- 4.9.9-REL released ---
+ 
+ 818. [bug]	remote buffer overrun.
+ 
  	--- 4.9.8-REL released ---
  
  817. [security]	do not call syslog() with unbounded network data.
Index: bind4/Makefile
diff -c bind4/Makefile:8.55 bind4/Makefile:8.56
*** bind4/Makefile:8.55	Sat Jan 27 15:29:22 2001
--- bind4/Makefile	Wed Jun 26 00:52:41 2002
***************
*** 52,58 ****
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! VER = 4.9.8-REL
  SHELL = /bin/sh
  MAKE = make
  DESTDIR =
--- 52,58 ----
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! VER = 4.9.9-REL
  SHELL = /bin/sh
  MAKE = make
  DESTDIR =
Index: bind4/README
diff -c bind4/README:8.9 bind4/README:8.10
*** bind4/README:8.9	Thu Dec 21 22:45:44 2000
--- bind4/README	Wed Jun 26 00:52:40 2002
***************
*** 1,10 ****
  Internet Software Consortium
! BIND Release 4.9.8 README
  $Date$
  
  The official version of ISC BIND is now 9.1.0, or failing that, 8.2.3.
  
! This is ISC BIND 4.9.8, 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.
--- 1,10 ----
  Internet Software Consortium
! BIND Release 4.9.9 README
  $Date$
  
  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
  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/res/gethnamaddr.c
diff -c bind4/res/gethnamaddr.c:8.23 bind4/res/gethnamaddr.c:8.24
*** bind4/res/gethnamaddr.c:8.23	Mon Apr  6 21:59:46 1998
--- bind4/res/gethnamaddr.c	Wed Jun 26 00:46:29 2002
***************
*** 111,117 ****
  static int stayopen = 0;
  
  static void map_v4v6_address __P((const char *src, char *dst));
! static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len));
  
  #ifdef RESOLVSORT
  static void addrsort __P((char **, int));
--- 111,117 ----
  static int stayopen = 0;
  
  static void map_v4v6_address __P((const char *src, char *dst));
! static void map_v4v6_hostent __P((struct hostent *hp, char **bp, char *ep));
  
  #ifdef RESOLVSORT
  static void addrsort __P((char **, int));
***************
*** 180,187 ****
  	register const u_char *cp;
  	register int n;
  	const u_char *eom, *erdata;
! 	char *bp, **ap, **hap;
! 	int type, class, buflen, ancount, qdcount;
  	int haveanswer, had_error;
  	int toobig = 0;
  	char tbuf[MAXDNAME];
--- 180,187 ----
  	register const u_char *cp;
  	register int n;
  	const u_char *eom, *erdata;
! 	char *bp, **ap, **hap, *ep;
! 	int type, class, ancount, qdcount;
  	int haveanswer, had_error;
  	int toobig = 0;
  	char tbuf[MAXDNAME];
***************
*** 209,222 ****
  	ancount = ntohs(hp->ancount);
  	qdcount = ntohs(hp->qdcount);
  	bp = hostbuf;
! 	buflen = 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);
  	if ((n < 0) || !(*name_ok)(bp)) {
  		h_errno = NO_RECOVERY;
  		return (NULL);
--- 209,222 ----
  	ancount = ntohs(hp->ancount);
  	qdcount = ntohs(hp->qdcount);
  	bp = 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, ep - bp);
  	if ((n < 0) || !(*name_ok)(bp)) {
  		h_errno = NO_RECOVERY;
  		return (NULL);
***************
*** 234,240 ****
  		}
  		host.h_name = bp;
  		bp += n;
- 		buflen -= n;
  		/* The qname can be abbreviated, but h_name is now absolute. */
  		qname = host.h_name;
  	}
--- 234,239 ----
***************
*** 247,253 ****
  	haveanswer = 0;
  	had_error = 0;
  	while (ancount-- > 0 && cp < eom && !had_error) {
! 		n = dn_expand(answer->buf, eom, cp, bp, buflen);
  		if ((n < 0) || !(*name_ok)(bp)) {
  			had_error++;
  			continue;
--- 246,252 ----
  	haveanswer = 0;
  	had_error = 0;
  	while (ancount-- > 0 && cp < eom && !had_error) {
! 		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
  		if ((n < 0) || !(*name_ok)(bp)) {
  			had_error++;
  			continue;
***************
*** 288,304 ****
  				continue;
  			}
  			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);
  			host.h_name = bp;
  			bp += n;
- 			buflen -= n;
  			continue;
  		}
  		if (qtype == T_PTR && type == T_CNAME) {
--- 287,301 ----
  				continue;
  			}
  			bp += n;
  			/* Get canonical name. */
  			n = strlen(tbuf) + 1;	/* for the \0 */
! 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
  				had_error++;
  				continue;
  			}
  			strcpy(bp, tbuf);
  			host.h_name = bp;
  			bp += n;
  			continue;
  		}
  		if (qtype == T_PTR && type == T_CNAME) {
***************
*** 314,327 ****
  			}
  			/* Get canonical name. */
  			n = strlen(tbuf) + 1;	/* for the \0 */
! 			if (n > buflen || n >= MAXHOSTNAMELEN) {
  				had_error++;
  				continue;
  			}
  			strcpy(bp, tbuf);
  			tname = bp;
  			bp += n;
- 			buflen -= n;
  			continue;
  		}
  		if (type != qtype) {
--- 311,323 ----
  			}
  			/* Get canonical name. */
  			n = strlen(tbuf) + 1;	/* for the \0 */
! 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
  				had_error++;
  				continue;
  			}
  			strcpy(bp, tbuf);
  			tname = bp;
  			bp += n;
  			continue;
  		}
  		if (type != qtype) {
***************
*** 340,346 ****
  				cp += n;
  				continue;	/* XXX - had_error++ ? */
  			}
! 			n = dn_expand(answer->buf, eom, cp, bp, buflen);
  			if ((n < 0) || !res_hnok(bp)) {
  				had_error++;
  				break;
--- 336,342 ----
  				cp += n;
  				continue;	/* XXX - had_error++ ? */
  			}
! 			n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
  			if ((n < 0) || !res_hnok(bp)) {
  				had_error++;
  				break;
***************
*** 364,370 ****
  					break;
  				}
  				bp += n;
- 				buflen -= n;
  			}
  			break;
  #else
--- 360,365 ----
***************
*** 376,383 ****
  					break;
  				}
  				bp += n;
! 				buflen -= n;
! 				map_v4v6_hostent(&host, &bp, &buflen);
  			}
  			h_errno = NETDB_SUCCESS;
  			return (&host);
--- 371,377 ----
  					break;
  				}
  				bp += n;
! 				map_v4v6_hostent(&host, &bp, ep);
  			}
  			h_errno = NETDB_SUCCESS;
  			return (&host);
***************
*** 400,406 ****
  				host.h_name = bp;
  				nn = strlen(bp) + 1;	/* for the \0 */
  				bp += nn;
- 				buflen -= nn;
  			}
  
  			bp += sizeof(align) - ((u_long)bp % sizeof(align));
--- 394,399 ----
***************
*** 419,425 ****
  			}
  			bcopy(cp, *hap++ = bp, n);
  			bp += n;
- 			buflen -= n;
  			cp += n;
  			if (cp != erdata) {
  				h_errno = NO_RECOVERY;
--- 412,417 ----
***************
*** 446,460 ****
  # endif /*RESOLVSORT*/
  		if (!host.h_name) {
  			n = strlen(qname) + 1;	/* for the \0 */
! 			if (n > buflen || 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);
  		h_errno = NETDB_SUCCESS;
  		return (&host);
  	}
--- 438,451 ----
  # endif /*RESOLVSORT*/
  		if (!host.h_name) {
  			n = strlen(qname) + 1;	/* for the \0 */
! 			if (n > ep - bp || n >= MAXHOSTNAMELEN)
  				goto no_recovery;
  			strcpy(bp, qname);
  			host.h_name = bp;
  			bp += n;
  		}
  		if (_res.options & RES_USE_INET6)
! 			map_v4v6_hostent(&host, &bp, ep);
  		h_errno = NETDB_SUCCESS;
  		return (&host);
  	}
***************
*** 488,495 ****
  {
  	querybuf buf;
  	register const char *cp;
! 	char *bp;
! 	int n, size, type, len;
  	extern struct hostent *_gethtbyname2();
  
  	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
--- 479,486 ----
  {
  	querybuf buf;
  	register const char *cp;
! 	char *bp, *ep;
! 	int n, size, type;
  	extern struct hostent *_gethtbyname2();
  
  	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
***************
*** 544,550 ****
  				strncpy(hostbuf, name, MAXDNAME);
  				hostbuf[MAXDNAME] = '\0';
  				bp = hostbuf + MAXDNAME;
! 				len = sizeof hostbuf - MAXDNAME;
  				host.h_name = hostbuf;
  				host.h_aliases = host_aliases;
  				host_aliases[0] = NULL;
--- 535,541 ----
  				strncpy(hostbuf, name, MAXDNAME);
  				hostbuf[MAXDNAME] = '\0';
  				bp = hostbuf + MAXDNAME;
! 				ep = hostbuf + sizeof hostbuf;
  				host.h_name = hostbuf;
  				host.h_aliases = host_aliases;
  				host_aliases[0] = NULL;
***************
*** 552,558 ****
  				h_addr_ptrs[1] = NULL;
  				host.h_addr_list = h_addr_ptrs;
  				if (_res.options & RES_USE_INET6)
! 					map_v4v6_hostent(&host, &bp, &len);
  				h_errno = NETDB_SUCCESS;
  				return (&host);
  			}
--- 543,549 ----
  				h_addr_ptrs[1] = NULL;
  				host.h_addr_list = h_addr_ptrs;
  				if (_res.options & RES_USE_INET6)
! 					map_v4v6_hostent(&host, &bp, ep);
  				h_errno = NETDB_SUCCESS;
  				return (&host);
  			}
***************
*** 577,583 ****
  				strncpy(hostbuf, name, MAXDNAME);
  				hostbuf[MAXDNAME] = '\0';
  				bp = hostbuf + MAXDNAME;
! 				len = sizeof hostbuf - MAXDNAME;
  				host.h_name = hostbuf;
  				host.h_aliases = host_aliases;
  				host_aliases[0] = NULL;
--- 568,574 ----
  				strncpy(hostbuf, name, MAXDNAME);
  				hostbuf[MAXDNAME] = '\0';
  				bp = hostbuf + MAXDNAME;
! 				ep = hostbuf + sizeof hostbuf;
  				host.h_name = hostbuf;
  				host.h_aliases = host_aliases;
  				host_aliases[0] = NULL;
***************
*** 884,893 ****
  }
  
  static void
! map_v4v6_hostent(hp, bpp, lenp)
  	struct hostent *hp;
  	char **bpp;
! 	int *lenp;
  {
  	char **ap;
  
--- 875,884 ----
  }
  
  static void
! map_v4v6_hostent(hp, bpp, ep)
  	struct hostent *hp;
  	char **bpp;
! 	char *ep;
  {
  	char **ap;
  
***************
*** 898,914 ****
  	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.  XXX */
  			*ap = NULL;
  			return;
  		}
  		*bpp += i;
- 		*lenp -= i;
  		map_v4v6_address(*ap, *bpp);
  		*ap = *bpp;
  		*bpp += IN6ADDRSZ;
- 		*lenp -= IN6ADDRSZ;
  	}
  }
  
--- 889,903 ----
  	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.  XXX */
  			*ap = NULL;
  			return;
  		}
  		*bpp += i;
  		map_v4v6_address(*ap, *bpp);
  		*ap = *bpp;
  		*bpp += IN6ADDRSZ;
  	}
  }
  
Index: bind4/res/getnetnamadr.c
diff -c bind4/res/getnetnamadr.c:8.8 bind4/res/getnetnamadr.c:8.9
*** bind4/res/getnetnamadr.c:8.8	Sun Jun  1 13:34:37 1997
--- bind4/res/getnetnamadr.c	Wed Jun 26 00:46:30 2002
***************
*** 98,106 ****
  	register u_char *cp;
  	register int n;
  	u_char *eom;
! 	int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
  	char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap,
! 		*paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
  static	struct netent net_entry;
  static	char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
  
--- 98,106 ----
  	register u_char *cp;
  	register int n;
  	u_char *eom;
! 	int type, class, ancount, qdcount, haveanswer, i, nchar;
  	char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap,
! 		*paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0, *ep;
  static	struct netent net_entry;
  static	char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
  
***************
*** 123,129 ****
  	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)
--- 123,129 ----
  	ancount = ntohs(hp->ancount); /* #/records in the answer section */
  	qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
  	bp = netbuf;
! 	ep = netbuf + sizeof(netbuf);
  	cp = answer->buf + HFIXEDSZ;
  	if (!qdcount) {
  		if (hp->aa)
***************
*** 139,145 ****
  	net_entry.n_aliases = net_aliases;
  	haveanswer = 0;
  	while (--ancount >= 0 && cp < eom) {
! 		n = dn_expand(answer->buf, eom, cp, bp, buflen);
  		if ((n < 0) || !res_dnok(bp))
  			break;
  		cp += n;
--- 139,145 ----
  	net_entry.n_aliases = net_aliases;
  	haveanswer = 0;
  	while (--ancount >= 0 && cp < eom) {
! 		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
  		if ((n < 0) || !res_dnok(bp))
  			break;
  		cp += n;
***************
*** 150,156 ****
  		cp += INT32SZ;		/* TTL */
  		GETSHORT(n, cp);
  		if (class == C_IN && type == T_PTR) {
! 			n = dn_expand(answer->buf, eom, cp, bp, buflen);
  			if ((n < 0) || !res_hnok(bp)) {
  				cp += n;
  				return (NULL);
--- 150,156 ----
  		cp += INT32SZ;		/* TTL */
  		GETSHORT(n, cp);
  		if (class == C_IN && type == T_PTR) {
! 			n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
  			if ((n < 0) || !res_hnok(bp)) {
  				cp += n;
  				return (NULL);
