From patchwork Fri Mar 25 19:03:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 11526 Received: (qmail 52534 invoked by alias); 25 Mar 2016 19:03:36 -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 52508 invoked by uid 89); 25 Mar 2016 19:03:36 -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=aliases X-HELO: mx1.redhat.com To: GNU C Library From: Florian Weimer Subject: [PATCH] nss_dns: Skip over non-PTR records in the netent code [BZ #19868] Message-ID: <56F58B81.3010306@redhat.com> Date: Fri, 25 Mar 2016 20:03:29 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 The DNS packet parser was broken and got de-synchronized by CNAME or RRSIG records. CNAME records are the larger problem because they come before the PTR records we are interested in. Curiously, this meant that the RDATA length check was not actually missing (it was implied by the loop condition). Florian 2016-03-25 Florian Weimer [BZ #19868] * resolv/nss_dns/dns-network.c (getanswer_r): Skip over non-PTR records. diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c index 2eb2f67..8d6ee0d 100644 --- a/resolv/nss_dns/dns-network.c +++ b/resolv/nss_dns/dns-network.c @@ -348,10 +348,23 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, if (n < 0 || res_dnok (bp) == 0) break; cp += n; + + if (end_of_message - cp < 10) + { + __set_h_errno (NO_RECOVERY); + return NSS_STATUS_UNAVAIL; + } + GETSHORT (type, cp); GETSHORT (class, cp); cp += INT32SZ; /* TTL */ - GETSHORT (n, cp); + uint16_t rdatalen; + GETSHORT (rdatalen, cp); + if (end_of_message - cp < rdatalen) + { + __set_h_errno (NO_RECOVERY); + return NSS_STATUS_UNAVAIL; + } if (class == C_IN && type == T_PTR) { @@ -373,7 +386,7 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, cp += n; return NSS_STATUS_UNAVAIL; } - cp += n; + cp += rdatalen; if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES]) { *alias_pointer++ = bp; @@ -384,6 +397,9 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, ++have_answer; } } + else + /* Skip over unknown record data. */ + cp += rdatalen; } if (have_answer)