From 39361f45df6a4390e513a8186444d9923dead912 Mon Sep 17 00:00:00 2001 From: itojun Date: Wed, 26 Jun 2002 06:00:50 +0000 Subject: avoid remote buffer overrun on hostbuf[]. From: Joost Pol correct bad practice in the code - it uses two changing variables to manage buffer (buf and buflen). we eliminate buflen and use fixed point (ep) as the ending pointer. this fix is critical. --- net/bind4/Makefile | 3 +- net/bind4/distinfo | 4 +- net/bind4/patches/patch-aa | 183 +++++++++++++++++++++++++++++++++++++++++++++ net/bind4/patches/patch-ab | 35 +++++++++ 4 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 net/bind4/patches/patch-aa create mode 100644 net/bind4/patches/patch-ab (limited to 'net') diff --git a/net/bind4/Makefile b/net/bind4/Makefile index 69e5bb3f55b..3534288e932 100644 --- a/net/bind4/Makefile +++ b/net/bind4/Makefile @@ -1,8 +1,9 @@ -# $NetBSD: Makefile,v 1.6 2001/09/09 20:36:37 agc Exp $ +# $NetBSD: Makefile,v 1.7 2002/06/26 06:00:50 itojun Exp $ # DISTNAME= bind-4.9.8-REL PKGNAME= bind-4.9.8 +PKGREVISION= 1 CATEGORIES= net MASTER_SITES= ftp://ftp.isc.org/isc/bind/src/DEPRECATED/4.9.8/ diff --git a/net/bind4/distinfo b/net/bind4/distinfo index f8fd84e295e..09f31d4826a 100644 --- a/net/bind4/distinfo +++ b/net/bind4/distinfo @@ -1,4 +1,6 @@ -$NetBSD: distinfo,v 1.2 2001/04/21 11:23:10 wiz Exp $ +$NetBSD: distinfo,v 1.3 2002/06/26 06:00:50 itojun Exp $ SHA1 (bind-4.9.8-REL.tar.gz) = bc690813c8e8bb3569ceee3c10ebfeb52b47ad00 Size (bind-4.9.8-REL.tar.gz) = 1972069 bytes +SHA1 (patch-aa) = ffa75c8725508b858b65021e93af113cea795ffd +SHA1 (patch-ab) = 2c0fd4ff56bf9087f4f70f3196e31e1217c282f5 diff --git a/net/bind4/patches/patch-aa b/net/bind4/patches/patch-aa new file mode 100644 index 00000000000..3fc1fae3e4e --- /dev/null +++ b/net/bind4/patches/patch-aa @@ -0,0 +1,183 @@ +$NetBSD: patch-aa,v 1.1 2002/06/26 06:00:50 itojun Exp $ + +--- res/gethnamaddr.c- Wed Jun 26 12:08:56 2002 ++++ res/gethnamaddr.c Wed Jun 26 12:13:12 2002 +@@ -112,5 +112,5 @@ + + static void map_v4v6_address __P((const char *src, char *dst)); +-static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len)); ++static void map_v4v6_hostent __P((struct hostent *hp, char **bp, char *ep)); + + #ifdef RESOLVSORT +@@ -181,6 +181,6 @@ + register int n; + const u_char *eom, *erdata; +- char *bp, **ap, **hap; +- int type, class, buflen, ancount, qdcount; ++ char *bp, **ap, **hap, *ep; ++ int type, class, ancount, qdcount; + int haveanswer, had_error; + int toobig = 0; +@@ -210,5 +210,5 @@ + qdcount = ntohs(hp->qdcount); + bp = hostbuf; +- buflen = sizeof hostbuf; ++ ep = hostbuf + sizeof hostbuf; + cp = answer->buf; + BOUNDED_INCR(HFIXEDSZ); +@@ -217,5 +217,5 @@ + 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; +@@ -235,5 +235,4 @@ + host.h_name = bp; + bp += n; +- buflen -= n; + /* The qname can be abbreviated, but h_name is now absolute. */ + qname = host.h_name; +@@ -248,5 +247,5 @@ + 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); + if ((n < 0) || !(*name_ok)(bp)) { + had_error++; +@@ -289,8 +288,7 @@ + } + 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; +@@ -299,5 +297,4 @@ + host.h_name = bp; + bp += n; +- buflen -= n; + continue; + } +@@ -315,5 +312,5 @@ + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ +- if (n > buflen || n >= MAXHOSTNAMELEN) { ++ if (n > ep - bp || n >= MAXHOSTNAMELEN) { + had_error++; + continue; +@@ -322,5 +319,4 @@ + tname = bp; + bp += n; +- buflen -= n; + continue; + } +@@ -341,5 +337,5 @@ + 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++; +@@ -365,5 +361,4 @@ + } + bp += n; +- buflen -= n; + } + break; +@@ -377,6 +372,5 @@ + } + bp += n; +- buflen -= n; +- map_v4v6_hostent(&host, &bp, &buflen); ++ map_v4v6_hostent(&host, &bp, ep); + } + h_errno = NETDB_SUCCESS; +@@ -401,5 +395,4 @@ + nn = strlen(bp) + 1; /* for the \0 */ + bp += nn; +- buflen -= nn; + } + +@@ -420,5 +413,4 @@ + bcopy(cp, *hap++ = bp, n); + bp += n; +- buflen -= n; + cp += n; + if (cp != erdata) { +@@ -447,13 +439,12 @@ + 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,6 +480,6 @@ + querybuf buf; + register const char *cp; +- char *bp; +- int n, size, type, len; ++ char *bp, *ep; ++ int n, size, type; + extern struct hostent *_gethtbyname2(); + +@@ -545,5 +536,5 @@ + hostbuf[MAXDNAME] = '\0'; + bp = hostbuf + MAXDNAME; +- len = sizeof hostbuf - MAXDNAME; ++ ep = hostbuf + sizeof hostbuf; + host.h_name = hostbuf; + host.h_aliases = host_aliases; +@@ -553,5 +544,5 @@ + 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; + return (&host); +@@ -578,5 +569,5 @@ + hostbuf[MAXDNAME] = '\0'; + bp = hostbuf + MAXDNAME; +- len = sizeof hostbuf - MAXDNAME; ++ ep = hostbuf + sizeof hostbuf; + host.h_name = hostbuf; + host.h_aliases = host_aliases; +@@ -885,8 +876,8 @@ + + static void +-map_v4v6_hostent(hp, bpp, lenp) ++map_v4v6_hostent(hp, bpp, ep) + struct hostent *hp; + char **bpp; +- int *lenp; ++ char *ep; + { + char **ap; +@@ -899,5 +890,5 @@ + int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); + +- if (*lenp < (i + IN6ADDRSZ)) { ++ if (ep - *bpp < (i + IN6ADDRSZ)) { + /* Out of memory. Truncate address list here. XXX */ + *ap = NULL; +@@ -905,9 +896,7 @@ + } + *bpp += i; +- *lenp -= i; + map_v4v6_address(*ap, *bpp); + *ap = *bpp; + *bpp += IN6ADDRSZ; +- *lenp -= IN6ADDRSZ; + } + } diff --git a/net/bind4/patches/patch-ab b/net/bind4/patches/patch-ab new file mode 100644 index 00000000000..2924aeaf625 --- /dev/null +++ b/net/bind4/patches/patch-ab @@ -0,0 +1,35 @@ +$NetBSD: patch-ab,v 1.1 2002/06/26 06:00:51 itojun Exp $ + +--- res/getnetnamadr.c- Wed Jun 26 12:09:06 2002 ++++ res/getnetnamadr.c Wed Jun 26 12:12:06 2002 +@@ -99,7 +99,7 @@ + register int n; + u_char *eom; +- int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; ++ 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; ++ *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0, *ep; + static struct netent net_entry; + static char *net_aliases[MAXALIASES], netbuf[PACKETSZ]; +@@ -124,5 +124,5 @@ + qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ + bp = netbuf; +- buflen = sizeof(netbuf); ++ ep = netbuf + sizeof(netbuf); + cp = answer->buf + HFIXEDSZ; + if (!qdcount) { +@@ -140,5 +140,5 @@ + 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; +@@ -151,5 +151,5 @@ + 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; -- cgit v1.2.3