summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/res_send.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-05-02 13:11:02 +0000
committerpeter <peter@FreeBSD.org>1998-05-02 13:11:02 +0000
commit119bf1955726447fe80a4419229bf6ca6a606026 (patch)
treeb507d8454b4648373f44ea660cc33052c678a495 /lib/libc/net/res_send.c
parent52007a8cf8e565a9578ec116b85253372aa5d810 (diff)
downloadFreeBSD-src-119bf1955726447fe80a4419229bf6ca6a606026.zip
FreeBSD-src-119bf1955726447fe80a4419229bf6ca6a606026.tar.gz
Update libc dns code to 4.9.7-T1B level. This involved chopping out large
chunks of res_comp.c and replacing it with chunks of bind-8.1.1's resolver code. (There are no interface changes though) The other parts are better bounds checking related.
Diffstat (limited to 'lib/libc/net/res_send.c')
-rw-r--r--lib/libc/net/res_send.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index 70a5c17..b8acbfd 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -55,8 +55,8 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
-static char orig_rcsid[] = "From: Id: res_send.c,v 8.13 1997/06/01 20:34:37 vixie Exp";
-static char rcsid[] = "$Id: res_send.c,v 1.19 1997/09/14 09:44:34 peter Exp $";
+static char orig_rcsid[] = "From: Id: res_send.c,v 8.14 1998/04/07 04:59:46 vixie Exp $";
+static char rcsid[] = "$Id: res_send.c,v 1.20 1997/09/16 06:03:54 peter Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -191,6 +191,8 @@ res_isourserver(inp)
/* int
* res_nameinquery(name, type, class, buf, eom)
* look for (name,type,class) in the query section of packet (buf,eom)
+ * requires:
+ * buf + HFIXESDZ <= eom
* returns:
* -1 : format error
* 0 : not found
@@ -215,6 +217,8 @@ res_nameinquery(name, type, class, buf, eom)
if (n < 0)
return (-1);
cp += n;
+ if (cp + 2 * INT16SZ > eom)
+ return (-1);
ttype = _getshort(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ;
if (ttype == type &&
@@ -244,6 +248,9 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
register const u_char *cp = buf1 + HFIXEDSZ;
int qdcount = ntohs(((HEADER*)buf1)->qdcount);
+ if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
+ return (-1);
+
if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
return (0);
while (qdcount-- > 0) {
@@ -254,6 +261,8 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
if (n < 0)
return (-1);
cp += n;
+ if (cp + 2 * INT16SZ > eom1)
+ return (-1);
ttype = _getshort(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ;
if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
@@ -279,6 +288,10 @@ res_send(buf, buflen, ans, anssiz)
/* errno should have been set by res_init() in this case. */
return (-1);
}
+ if (anssiz < HFIXEDSZ) {
+ errno = EINVAL;
+ return (-1);
+ }
DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
(stdout, ";; res_send()\n"), buf, buflen);
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
@@ -423,6 +436,17 @@ read_len:
len = anssiz;
} else
len = resplen;
+ if (len < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n", len));
+ terrno = EMSGSIZE;
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
cp = ans;
while (len != 0 &&
(n = read(s, (char *)cp, (int)len)) > 0) {
@@ -590,6 +614,11 @@ read_len:
timeout.tv_sec = 1;
}
wait:
+ if (s < 0) {
+ Perror(stderr, "s out-of-bounds", EMFILE);
+ res_close();
+ goto next_ns;
+ }
if (use_poll) {
struct sigaction sa, osa;
int sigsys_installed = 0;
@@ -662,6 +691,18 @@ read_len:
goto next_ns;
}
gotsomewhere = 1;
+ if (resplen < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n",
+ resplen));
+ terrno = EMSGSIZE;
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
if (hp->id != anhp->id) {
/*
* response from old query, ignore it.
OpenPOWER on IntegriCloud