From 514aeac2acbbe2b77ff3c4e310617523cf5651c5 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 7 Dec 2006 06:57:46 +0000 Subject: [PATCH] 2118. [bug] Handle response with long chains of domain name compression pointers which point to other compression pointers. [RT #16427] --- CHANGES | 4 ++++ lib/dns/name.c | 20 +++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index f90d4b9056..855d27ca12 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +2118. [bug] Handle response with long chains of domain name + compression pointers which point to other compression + pointers. [RT #16427] + 2117. [bug] DNSSEC fixes: named could fail to cache NSEC records which could lead to validation failures. named didn't handle negative DS responses that were in the process diff --git a/lib/dns/name.c b/lib/dns/name.c index b5bd0dd29d..b2d0998d0d 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.160 2006/12/04 01:52:46 marka Exp $ */ +/* $Id: name.c,v 1.161 2006/12/07 06:57:46 marka Exp $ */ /*! \file */ @@ -1722,7 +1722,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, { unsigned char *cdata, *ndata; unsigned int cused; /* Bytes of compressed name data used */ - unsigned int hops, nused, labels, n, nmax; + unsigned int nused, labels, n, nmax; unsigned int current, new_current, biggest_pointer; isc_boolean_t done; fw_state state = fw_start; @@ -1730,10 +1730,12 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, unsigned char *offsets; dns_offsets_t odata; isc_boolean_t downcase; + isc_boolean_t seen_pointer; /* * Copy the possibly-compressed name at source into target, - * decompressing it. + * decompressing it. Loop prevention is performed by checking + * the new pointer against biggest_pointer. */ REQUIRE(VALID_NAME(name)); @@ -1767,11 +1769,11 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, * Set up. */ labels = 0; - hops = 0; done = ISC_FALSE; ndata = isc_buffer_used(target); nused = 0; + seen_pointer = ISC_FALSE; /* * Find the maximum number of uncompressed target name @@ -1797,7 +1799,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, while (current < source->active && !done) { c = *cdata++; current++; - if (hops == 0) + if (!seen_pointer) cused++; switch (state) { @@ -1853,11 +1855,8 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, return (DNS_R_BADPOINTER); biggest_pointer = new_current; current = new_current; - cdata = (unsigned char *)source->base + - current; - hops++; - if (hops > DNS_POINTER_MAXHOPS) - return (DNS_R_TOOMANYHOPS); + cdata = (unsigned char *)source->base + current; + seen_pointer = ISC_TRUE; state = fw_start; break; default: @@ -1893,7 +1892,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, * big enough buffer. */ return (ISC_R_NOSPACE); - } isc_result_t