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 ++++++++++++++++------------------------ src/lib/libc/net/getnetnamadr.c | 19 +++++++------- 2 files changed, 33 insertions(+), 43 deletions(-) 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; } } diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c index 0ebc77b656..522332d9b0 100644 --- a/src/lib/libc/net/getnetnamadr.c +++ b/src/lib/libc/net/getnetnamadr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getnetnamadr.c,v 1.13 1999/06/04 06:38:10 niklas Exp $ */ +/* $OpenBSD: getnetnamadr.c,v 1.13.8.1 2002/06/26 06:02:54 millert Exp $ */ /* * Copyright (c) 1997, Jason Downs. All rights reserved. @@ -77,7 +77,7 @@ static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; #else -static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.13 1999/06/04 06:38:10 niklas Exp $"; +static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.13.8.1 2002/06/26 06:02:54 millert Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -133,9 +133,9 @@ getnetanswer(answer, anslen, net_i) register u_char *cp; 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[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN]; - char *in, *st, *pauxt, *bp, **ap; + char *in, *st, *pauxt, *bp, **ap, *ep; char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; static struct netent net_entry; static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; @@ -159,7 +159,7 @@ getnetanswer(answer, anslen, net_i) ancount = ntohs(hp->ancount); /* #/records in the answer section */ qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ bp = netbuf; - buflen = sizeof(netbuf); + ep = netbuf + sizeof(netbuf); cp = answer->buf + HFIXEDSZ; if (!qdcount) { if (hp->aa) @@ -175,7 +175,7 @@ getnetanswer(answer, anslen, net_i) net_entry.n_aliases = net_aliases; 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); #ifdef USE_RESOLV_NAME_OK if ((n < 0) || !res_dnok(bp)) #else @@ -191,12 +191,13 @@ getnetanswer(answer, anslen, net_i) cp += INT32SZ; /* TTL */ 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); #ifdef USE_RESOLV_NAME_OK - if ((n < 0) || !res_hnok(bp)) { + if ((n < 0) || !res_hnok(bp)) #else - if ((n < 0) || !_hokchar(bp)) { + if ((n < 0) || !_hokchar(bp)) #endif + { cp += n; return (NULL); } -- cgit v1.2.3-55-g6feb