From 0375e51a80c9a3f6ac5804f1c784f90c8ed7a3c3 Mon Sep 17 00:00:00 2001 From: millert <> Date: Wed, 26 Jun 2002 06:02:54 +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. From: itojun this fix is critical. --- src/lib/libc/net/gethostnamadr.c | 57 ++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 34 deletions(-) (limited to 'src/lib/libc/net/gethostnamadr.c') diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c index 33c9643f70..c3381a73d0 100644 --- a/src/lib/libc/net/gethostnamadr.c +++ b/src/lib/libc/net/gethostnamadr.c @@ -52,7 +52,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.42 2000/07/30 14:07:14 itojun Exp $"; +static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.42.4.1 2002/06/26 06:02:54 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include @@ -99,7 +99,7 @@ static FILE *hostf = NULL; 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)); +static void map_v4v6_hostent __P((struct hostent *hp, char **bp, char *)); #ifdef RESOLVSORT static void addrsort __P((char **, int)); @@ -169,8 +169,8 @@ getanswer(answer, anslen, qname, qtype) register const u_char *cp; register int n; const u_char *eom; - 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; char tbuf[MAXDNAME]; @@ -204,13 +204,13 @@ getanswer(answer, anslen, qname, qtype) ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = hostbuf; - buflen = sizeof hostbuf; + ep = hostbuf + sizeof hostbuf; cp = answer->buf + HFIXEDSZ; if (qdcount != 1) { h_errno = NO_RECOVERY; 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; return (NULL); @@ -224,7 +224,6 @@ getanswer(answer, anslen, qname, qtype) n = strlen(bp) + 1; /* for the \0 */ host.h_name = bp; bp += n; - buflen -= n; /* The qname can be abbreviated, but h_name is now absolute. */ qname = host.h_name; } @@ -237,7 +236,7 @@ getanswer(answer, anslen, qname, qtype) haveanswer = 0; 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++; continue; @@ -272,17 +271,15 @@ getanswer(answer, anslen, qname, qtype) *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) { + if (n > ep - bp) { had_error++; continue; } strcpy(bp, tbuf); host.h_name = bp; bp += n; - buflen -= n; continue; } if (qtype == T_PTR && type == T_CNAME) { @@ -298,14 +295,13 @@ getanswer(answer, anslen, qname, qtype) cp += n; /* 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 (type != qtype) { @@ -324,7 +320,7 @@ getanswer(answer, anslen, qname, qtype) cp += n; continue; /* XXX - had_error++ ? */ } - n = dn_expand(answer->buf, eom, cp, bp, buflen); + n = dn_expand(answer->buf, eom, cp, bp, ep - bp); #ifdef USE_RESOLV_NAME_OK if ((n < 0) || !res_hnok(bp)) { #else @@ -344,7 +340,6 @@ getanswer(answer, anslen, qname, qtype) if (n != -1) { n = strlen(bp) + 1; /* for the \0 */ bp += n; - buflen -= n; } break; #else @@ -352,8 +347,7 @@ getanswer(answer, anslen, qname, qtype) if (_res.options & RES_USE_INET6) { n = strlen(bp) + 1; /* for the \0 */ bp += n; - buflen -= n; - map_v4v6_hostent(&host, &bp, &buflen); + map_v4v6_hostent(&host, &bp, ep); } h_errno = NETDB_SUCCESS; return (&host); @@ -376,7 +370,6 @@ getanswer(answer, anslen, qname, qtype) host.h_name = bp; nn = strlen(bp) + 1; /* for the \0 */ bp += nn; - buflen -= nn; } bp += sizeof(align) - ((u_long)bp % sizeof(align)); @@ -400,7 +393,6 @@ getanswer(answer, anslen, qname, qtype) } bcopy(cp, *hap++ = bp, n); bp += n; - buflen -= n; cp += n; break; } @@ -421,15 +413,14 @@ getanswer(answer, anslen, qname, qtype) # endif /*RESOLVSORT*/ if (!host.h_name) { n = strlen(qname) + 1; /* for the \0 */ - if (n > buflen) + if (n > ep - bp) goto try_again; 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); } @@ -521,8 +512,8 @@ gethostbyname2(name, af) { querybuf buf; register const char *cp; - char *bp; - int n, size, type, len, i; + char *bp, *ep; + int n, size, type, i; extern struct hostent *_gethtbyname2(), *_yp_gethtbyname(); register struct hostent *hp; char lookups[MAXDNSLUS]; @@ -577,7 +568,7 @@ gethostbyname2(name, af) strncpy(hostbuf, name, MAXHOSTNAMELEN-1); hostbuf[MAXHOSTNAMELEN-1] = '\0'; bp = hostbuf + MAXHOSTNAMELEN; - len = sizeof hostbuf - MAXHOSTNAMELEN; + ep = hostbuf + sizeof(hostbuf); host.h_name = hostbuf; host.h_aliases = host_aliases; host_aliases[0] = NULL; @@ -585,7 +576,7 @@ gethostbyname2(name, af) h_addr_ptrs[1] = NULL; 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); } @@ -610,7 +601,7 @@ gethostbyname2(name, af) strncpy(hostbuf, name, MAXHOSTNAMELEN-1); hostbuf[MAXHOSTNAMELEN-1] = '\0'; bp = hostbuf + MAXHOSTNAMELEN; - len = sizeof hostbuf - MAXHOSTNAMELEN; + ep = hostbuf + sizeof(hostbuf); host.h_name = hostbuf; host.h_aliases = host_aliases; host_aliases[0] = NULL; @@ -869,9 +860,9 @@ _gethtent() *q = NULL; if (_res.options & RES_USE_INET6) { char *bp = hostbuf; - int buflen = sizeof hostbuf; + char *ep = hostbuf + sizeof hostbuf; - map_v4v6_hostent(&host, &bp, &buflen); + map_v4v6_hostent(&host, &bp, ep); } h_errno = NETDB_SUCCESS; return (&host); @@ -1087,10 +1078,10 @@ map_v4v6_address(src, dst) } 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; @@ -1101,17 +1092,15 @@ map_v4v6_hostent(hp, bpp, lenp) for (ap = hp->h_addr_list; *ap; ap++) { 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; return; } *bpp += i; - *lenp -= i; map_v4v6_address(*ap, *bpp); *ap = *bpp; *bpp += IN6ADDRSZ; - *lenp -= IN6ADDRSZ; } } -- cgit v1.2.3-55-g6feb