summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-26 06:00:55 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-26 06:00:55 +0000
commite40c48d42917506d1a5e208a35251c588f4f104d (patch)
tree11351835c7e12e3b7ee0c0f287642fdd15b47676
parent6da00dfdfb22bc8dc066f7cdfc30fc850affdd19 (diff)
avoid remote buffer overrun on hostbuf[]. From: Joost Pol <joost@pine.nl>
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.
-rw-r--r--lib/libc/net/gethostnamadr.c57
-rw-r--r--lib/libc/net/getnetnamadr.c19
2 files changed, 33 insertions, 43 deletions
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
index cdc42c43298..3049d576e10 100644
--- a/lib/libc/net/gethostnamadr.c
+++ b/lib/libc/net/gethostnamadr.c
@@ -52,7 +52,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.47 2002/05/22 04:31:14 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.48 2002/06/26 06:00:53 itojun Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -99,7 +99,7 @@ static FILE *hostf = NULL;
static int stayopen = 0;
static void map_v4v6_address(const char *src, char *dst);
-static void map_v4v6_hostent(struct hostent *hp, char **bp, int *len);
+static void map_v4v6_hostent(struct hostent *hp, char **bp, char *);
#ifdef RESOLVSORT
static void addrsort(char **, int);
@@ -168,8 +168,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];
@@ -203,13 +203,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);
@@ -223,7 +223,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;
}
@@ -236,7 +235,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;
@@ -271,17 +270,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) {
@@ -297,14 +294,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) {
@@ -323,7 +319,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
@@ -343,7 +339,6 @@ getanswer(answer, anslen, qname, qtype)
if (n != -1) {
n = strlen(bp) + 1; /* for the \0 */
bp += n;
- buflen -= n;
}
break;
#else
@@ -351,8 +346,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);
@@ -375,7 +369,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));
@@ -399,7 +392,6 @@ getanswer(answer, anslen, qname, qtype)
}
bcopy(cp, *hap++ = bp, n);
bp += n;
- buflen -= n;
cp += n;
break;
}
@@ -420,15 +412,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);
}
@@ -520,8 +511,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];
@@ -575,7 +566,7 @@ gethostbyname2(name, af)
}
strlcpy(hostbuf, name, MAXHOSTNAMELEN);
bp = hostbuf + MAXHOSTNAMELEN;
- len = sizeof hostbuf - MAXHOSTNAMELEN;
+ ep = hostbuf + sizeof(hostbuf);
host.h_name = hostbuf;
host.h_aliases = host_aliases;
host_aliases[0] = NULL;
@@ -583,7 +574,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);
}
@@ -607,7 +598,7 @@ gethostbyname2(name, af)
}
strlcpy(hostbuf, name, MAXHOSTNAMELEN);
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);
@@ -1085,10 +1076,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;
@@ -1099,17 +1090,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/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c
index 834ddf11ae2..a5a4200acf1 100644
--- a/lib/libc/net/getnetnamadr.c
+++ b/lib/libc/net/getnetnamadr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnetnamadr.c,v 1.15 2002/02/16 21:27:23 millert Exp $ */
+/* $OpenBSD: getnetnamadr.c,v 1.16 2002/06/26 06:00:54 itojun 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.15 2002/02/16 21:27:23 millert Exp $";
+static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.16 2002/06/26 06:00:54 itojun 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
@@ -190,12 +190,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);
}