Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/net avoid remote buffer overrun on hostbuf[]. From...
details: https://anonhg.NetBSD.org/src/rev/a47542e5a9e5
branches: trunk
changeset: 533259:a47542e5a9e5
user: itojun <itojun%NetBSD.org@localhost>
date: Wed Jun 26 06:00:07 2002 +0000
description:
avoid remote buffer overrun on hostbuf[]. From: Joost Pol <joost%pine.nl@localhost>
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.
diffstat:
lib/libc/net/gethnamaddr.c | 55 ++++++++++++++++++---------------------------
lib/libc/net/getnetnamadr.c | 14 +++++-----
2 files changed, 29 insertions(+), 40 deletions(-)
diffs (295 lines):
diff -r ccd5207450d1 -r a47542e5a9e5 lib/libc/net/gethnamaddr.c
--- a/lib/libc/net/gethnamaddr.c Wed Jun 26 02:40:46 2002 +0000
+++ b/lib/libc/net/gethnamaddr.c Wed Jun 26 06:00:07 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gethnamaddr.c,v 1.45 2002/06/26 02:40:46 itojun Exp $ */
+/* $NetBSD: gethnamaddr.c,v 1.46 2002/06/26 06:00:07 itojun Exp $ */
/*
* ++Copyright++ 1985, 1988, 1993
@@ -61,7 +61,7 @@
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "Id: gethnamaddr.c,v 8.21 1997/06/01 20:34:37 vixie Exp ";
#else
-__RCSID("$NetBSD: gethnamaddr.c,v 1.45 2002/06/26 02:40:46 itojun Exp $");
+__RCSID("$NetBSD: gethnamaddr.c,v 1.46 2002/06/26 06:00:07 itojun Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -147,7 +147,7 @@
static struct hostent *getanswer __P((const querybuf *, int,
const char *, int));
static void map_v4v6_address __P((const char *, char *));
-static void map_v4v6_hostent __P((struct hostent *, char **, int *));
+static void map_v4v6_hostent __P((struct hostent *, char **, char *));
#ifdef RESOLVSORT
static void addrsort __P((char **, int));
#endif
@@ -229,8 +229,8 @@
const u_char *cp;
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;
char tbuf[MAXDNAME];
@@ -261,14 +261,14 @@
ancount = ntohs(hp->ancount);
qdcount = ntohs(hp->qdcount);
bp = hostbuf;
- buflen = sizeof 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, buflen);
+ n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
if ((n < 0) || !(*name_ok)(bp)) {
h_errno = NO_RECOVERY;
return (NULL);
@@ -286,7 +286,6 @@
}
host.h_name = bp;
bp += n;
- buflen -= n;
/* The qname can be abbreviated, but h_name is now absolute. */
qname = host.h_name;
}
@@ -299,7 +298,7 @@
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;
@@ -340,17 +339,15 @@
continue;
}
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;
}
strcpy(bp, tbuf);
host.h_name = bp;
bp += n;
- buflen -= n;
continue;
}
if (qtype == T_PTR && type == T_CNAME) {
@@ -366,14 +363,13 @@
}
/* Get canonical name. */
n = strlen(tbuf) + 1; /* for the \0 */
- if (n > buflen || n >= MAXHOSTNAMELEN) {
+ if (n > ep - bp || n >= MAXHOSTNAMELEN) {
had_error++;
continue;
}
strcpy(bp, tbuf);
tname = bp;
bp += n;
- buflen -= n;
continue;
}
if (type != qtype) {
@@ -393,7 +389,7 @@
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);
if ((n < 0) || !res_hnok(bp)) {
had_error++;
break;
@@ -417,7 +413,6 @@
break;
}
bp += n;
- buflen -= n;
}
break;
#else
@@ -429,8 +424,7 @@
break;
}
bp += n;
- buflen -= n;
- map_v4v6_hostent(&host, &bp, &buflen);
+ map_v4v6_hostent(&host, &bp, ep);
}
h_errno = NETDB_SUCCESS;
return (&host);
@@ -453,7 +447,6 @@
host.h_name = bp;
nn = strlen(bp) + 1; /* for the \0 */
bp += nn;
- buflen -= nn;
}
bp += sizeof(align) -
@@ -473,7 +466,6 @@
}
(void)memcpy(*hap++ = bp, cp, (size_t)n);
bp += n;
- buflen -= n;
cp += n;
if (cp != erdata) {
h_errno = NO_RECOVERY;
@@ -500,15 +492,14 @@
# endif /*RESOLVSORT*/
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);
}
@@ -543,8 +534,8 @@
int af;
{
const char *cp;
- char *bp;
- int size, len;
+ char *bp, *ep;
+ int size;
struct hostent *hp;
static const ns_dtab dtab[] = {
NS_FILES_CB(_gethtbyname, NULL)
@@ -601,7 +592,7 @@
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
bp = hostbuf + MAXDNAME;
- len = sizeof hostbuf - MAXDNAME;
+ ep = hostbuf + sizeof hostbuf;
host.h_name = hostbuf;
host.h_aliases = host_aliases;
host_aliases[0] = NULL;
@@ -609,7 +600,7 @@
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);
}
@@ -635,7 +626,7 @@
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
bp = hostbuf + MAXDNAME;
- len = sizeof hostbuf - MAXDNAME;
+ ep = hostbuf + sizeof hostbuf;
host.h_name = hostbuf;
host.h_aliases = host_aliases;
host_aliases[0] = NULL;
@@ -991,10 +982,10 @@
}
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;
@@ -1009,17 +1000,15 @@
for (ap = hp->h_addr_list; *ap; ap++) {
int i = sizeof(align) - (size_t)((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 -r ccd5207450d1 -r a47542e5a9e5 lib/libc/net/getnetnamadr.c
--- a/lib/libc/net/getnetnamadr.c Wed Jun 26 02:40:46 2002 +0000
+++ b/lib/libc/net/getnetnamadr.c Wed Jun 26 06:00:07 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: getnetnamadr.c,v 1.21 2002/05/26 14:48:19 wiz Exp $ */
+/* $NetBSD: getnetnamadr.c,v 1.22 2002/06/26 06:00:07 itojun Exp $ */
/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
* Dep. Matematica Universidade de Coimbra, Portugal, Europe
@@ -47,7 +47,7 @@
static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
static char rcsid[] = "Id: getnetnamadr.c,v 8.8 1997/06/01 20:34:37 vixie Exp ";
#else
-__RCSID("$NetBSD: getnetnamadr.c,v 1.21 2002/05/26 14:48:19 wiz Exp $");
+__RCSID("$NetBSD: getnetnamadr.c,v 1.22 2002/06/26 06:00:07 itojun Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -133,9 +133,9 @@
u_char *cp;
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 char netbuf[PACKETSZ];
_DIAGASSERT(answer != NULL);
@@ -159,7 +159,7 @@
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 @@
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);
if ((n < 0) || !res_dnok(bp))
break;
cp += n;
@@ -186,7 +186,7 @@
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);
if ((n < 0) || !res_hnok(bp)) {
cp += n;
return (NULL);
Home |
Main Index |
Thread Index |
Old Index