Skip site navigation (1)Skip section navigation (2)
Date:      26 Apr 2000 15:25:23 +1000
From:      john@nlc.net.au
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/18221: DNS resolver can fail for large DNS responses
Message-ID:  <20000426052523.85416.qmail@grunt.nlc.net.au>

next in thread | raw e-mail | index | archive | help

>Number:         18221
>Category:       bin
>Synopsis:       DNS resolver can fail for large DNS responses
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr 25 22:30:02 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     John Saunders
>Release:        FreeBSD 3.4-STABLE i386
>Organization:
NORTHLINK COMMUNICATIONS
>Environment:

	FreeBSD-3.4 (STABLE). However also applies to 4.0-STABLE and
	possibly -current.

>Description:

	The file /usr/src/lib/libc/net/gethostbydns.c can fail to
	resolve a name if the DNS response is very large. A small
	patch was made a little while ago to prevent a buffer overrun
	from occuring, however this patch prevents all DNS responses.

	The following patch causes a partial result to be returned
	that is limited to the size of the static buffer. This is
	preferable to the current situation of not returning anything.

>How-To-Repeat:

	Do an nslookup on any DNS name that has enough results to
	overflow a 1024 byte buffer.

>Fix:
	
--- lib/libc/net/gethostbydns.c.orig	Sat Feb 26 11:55:47 2000
+++ lib/libc/net/gethostbydns.c	Wed Mar  1 15:03:57 2000
@@ -142,12 +142,7 @@
 	} while (0)
 
 #define BOUNDS_CHECK(ptr, count) \
-	do { \
-		if ((ptr) + (count) > eom) { \
-			h_errno = NO_RECOVERY; \
-			return (NULL); \
-		} \
-	} while (0)
+	((ptr) + (count) > eom)
 
 static struct hostent *
 gethostanswer(answer, anslen, qname, qtype)
@@ -170,7 +165,7 @@
 
 	tname = qname;
 	host.h_name = NULL;
-	eom = answer->buf + anslen;
+	eom = answer->buf + (anslen > MAXPACKET ? MAXPACKET : anslen);
 	switch (qtype) {
 	case T_A:
 	case T_AAAA:
@@ -235,7 +230,11 @@
 			continue;
 		}
 		cp += n;			/* name */
-		BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
+		if (BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ))
+		{
+			had_error++;
+			continue;
+		}
 		type = _getshort(cp);
  		cp += INT16SZ;			/* type */
 		class = _getshort(cp);
@@ -245,7 +244,11 @@
 		cp += INT32SZ;			/* TTL */
 		n = _getshort(cp);
 		cp += INT16SZ;			/* len */
-		BOUNDS_CHECK(cp, n);
+		if (BOUNDS_CHECK(cp, n))
+		{
+			had_error++;
+			continue;
+		}
 		erdata = cp + n;
 		if (class != C_IN) {
 			/* XXX - debug? syslog? */
@@ -666,7 +669,6 @@
 	}
 	if (n > sizeof buf.buf) {
 		dprintf("static buffer is too small (%d)\n", n);
-		return (NULL);
 	}
 	if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR)))
 		return (NULL);	/* h_errno was set by gethostanswer() */



>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000426052523.85416.qmail>