From patchwork Fri Mar 25 18:57:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 602089 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qWsxd5CTTz9s9Z for ; Sat, 26 Mar 2016 05:57:41 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=yc7Zk7T3; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:message-id:date:mime-version :content-type; q=dns; s=default; b=qTOelfFwzYfpZf42o38uyFyE3BU7y xpeUuY1pwu15HycwCwAh8KxGUs5YeSU1+JI/5TMRRdNE6i+U2Mb/vpQiPOWy0Yq1 yqWTcgraxz5h4oL4SGMVbXpeUP3dURPgI1xPM5ROy9XkozAist05VzKSL4muhdBn AGB04cFskpPxiQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:message-id:date:mime-version :content-type; s=default; bh=dqmNOVQLnWqMu9X9ECWjJ1eJCdI=; b=yc7 Zk7T3sCTbzPgkXtoFDT0RplI8SFk0nFS/e9l4aprVQ3vZyQB/2KaCNCVg/Du9uiD VKRimp5sHuSPWRm/6opTky4H/Z7Ipa5uYsA0YnaixP4RZRTamm/KkjHiYQf7awIb mIb9kS+JN/FvoZkndfQCmMU07B4tr3GHSSefzogs= Received: (qmail 39306 invoked by alias); 25 Mar 2016 18:57:35 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 39281 invoked by uid 89); 25 Mar 2016 18:57:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=103, 6, 1036, xxx, 2016-03-25 X-HELO: mx1.redhat.com To: GNU C Library From: Florian Weimer Subject: [PATCH] nss_dns: Validate RDATA length against packet length [BZ #19830] Message-ID: <56F58A1A.1090603@redhat.com> Date: Fri, 25 Mar 2016 19:57:30 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In _nss_dns_getcanonname_r, a check for the availability of RR metadata was missing as well. Florian 2016-03-25 Florian Weimer [BZ #19830] * resolv/nss_dns/dns-host.c (getanswer_r): Check RDATA length. (gaih_getanswer_slice): Likewise. * resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Likewise. Also check for availability of RR metadata. diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c index 27255fd..5c5c6db 100644 --- a/resolv/nss_dns/dns-canon.c +++ b/resolv/nss_dns/dns-canon.c @@ -103,6 +103,11 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, ptr += s; + /* Check that there are enough bytes for the RR + metadata. */ + if (endptr - ptr < 10) + goto unavail; + /* Check whether type and class match. */ uint_fast16_t type; NS_GET16 (type, ptr); @@ -137,11 +142,16 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, if (__ns_get16 (ptr) != ns_c_in) goto unavail; - /* Also skip over the TTL. */ + /* Also skip over class and TTL. */ ptr += sizeof (uint16_t) + sizeof (uint32_t); - /* Skip over the data length and data. */ - ptr += sizeof (uint16_t) + __ns_get16 (ptr); + /* Skip over RDATA length and RDATA itself. */ + uint16_t rdatalen = __ns_get16 (ptr); + ptr += sizeof (uint16_t); + /* Not enough room for RDATA. */ + if (endptr - ptr < rdatalen) + goto unavail; + ptr += rdatalen; } } } diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 8599f4c..4bb0e62 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -751,6 +751,14 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, cp += INT32SZ; /* TTL */ n = __ns_get16 (cp); cp += INT16SZ; /* len */ + + if (end_of_message - cp < n) + { + /* RDATA extends beyond the end of the packet. */ + ++had_error; + continue; + } + if (__glibc_unlikely (class != C_IN)) { /* XXX - debug? syslog? */ @@ -1077,6 +1085,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, n = __ns_get16 (cp); cp += INT16SZ; /* len */ + if (end_of_message - cp < n) + { + /* RDATA extends beyond the end of the packet. */ + ++had_error; + continue; + } + if (class != C_IN) { cp += n;