From: Mark Andrews Date: Thu, 7 Dec 2006 07:02:47 +0000 (+0000) Subject: 2118. [bug] Handle response with long chains of domain name X-Git-Tag: v9.2.0b1^2~175 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=c08f16ae8b1bbb98df95c48f95f99d57a48aae16;p=thirdparty%2Fbind9.git 2118. [bug] Handle response with long chains of domain name compression pointers which point to other compression pointers. [RT #16427] --- diff --git a/CHANGES b/CHANGES index ea8ebb2c55c..c2e7313186d 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] + 2116. [bug] 'rndc reload' could cause the cache to continually be cleaned. [RT #16401] diff --git a/lib/dns/name.c b/lib/dns/name.c index 99694492955..2f868fb3d5e 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.127.2.14 2006/03/02 00:37:17 marka Exp $ */ +/* $Id: name.c,v 1.127.2.15 2006/12/07 07:02:47 marka Exp $ */ #include @@ -2347,17 +2347,19 @@ 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 saw_bitstring, done; fw_state state = fw_start; unsigned int c; unsigned char *offsets; dns_offsets_t odata; + 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)); @@ -2389,12 +2391,12 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, * Set up. */ labels = 0; - hops = 0; saw_bitstring = ISC_FALSE; done = ISC_FALSE; ndata = isc_buffer_used(target); nused = 0; + seen_pointer = ISC_FALSE; /* * Find the maximum number of uncompressed target name @@ -2420,7 +2422,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) { @@ -2498,11 +2500,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: @@ -2541,7 +2540,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, * big enough buffer. */ return (ISC_R_NOSPACE); - } isc_result_t