From owner-freebsd-bugs Tue Apr 25 22:30:11 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 7A88737BA40 for ; Tue, 25 Apr 2000 22:30:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id WAA08483; Tue, 25 Apr 2000 22:30:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from nhj.nlc.net.au (nhj.nlc.net.au [203.24.133.1]) by hub.freebsd.org (Postfix) with SMTP id B970837B765 for ; Tue, 25 Apr 2000 22:25:28 -0700 (PDT) (envelope-from john@nlc.net.au) Received: (qmail 17667 invoked from network); 26 Apr 2000 15:25:26 +1000 Received: from grunt.nlc.net.au (203.24.133.5) by nhj.nlc.net.au with SMTP; 26 Apr 2000 15:25:26 +1000 Received: (qmail 85417 invoked by uid 1000); 26 Apr 2000 15:25:24 +1000 Message-Id: <20000426052523.85416.qmail@grunt.nlc.net.au> Date: 26 Apr 2000 15:25:23 +1000 From: john@nlc.net.au Reply-To: john@nlc.net.au To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: bin/18221: DNS resolver can fail for large DNS responses Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >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