From: Kees Monshouwer Date: Mon, 4 May 2015 20:56:06 +0000 (+0200) Subject: add redirect loop safeguard in dnsname X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~28^2~64^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9114819cc4c5dad50ba92c8a9ab8d852811db365;p=pdns add redirect loop safeguard in dnsname --- diff --git a/pdns/dnsname.cc b/pdns/dnsname.cc index 8f1bb5b0f..a3d2778e9 100644 --- a/pdns/dnsname.cc +++ b/pdns/dnsname.cc @@ -20,6 +20,7 @@ DNSName::DNSName(const char* p) DNSName::DNSName(const char* pos, int len, int offset, bool uncompress, uint16_t* qtype, uint16_t* qclass, unsigned int* consumed) { + d_recurse = 0; packetParser(pos, len, offset, uncompress, qtype, qclass, consumed); } @@ -38,9 +39,11 @@ void DNSName::packetParser(const char* pos, int len, int offset, bool uncompress labellen &= (~0xc0); int newpos = (labellen << 8) + *(const unsigned char*)pos; - if(newpos < offset) + if(newpos < offset) { + if (++d_recurse > 100) + throw std::range_error("Abort label decompression after 100 redirects"); packetParser(opos, len, newpos, true); - else + } else throw std::range_error("Found a forward reference during label decompression"); pos++; break; diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index f2b83a6d6..de5623502 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -60,6 +60,7 @@ private: // typedef __gnu_cxx::__sso_string string_t; typedef std::string string_t; string_t d_storage; + int d_recurse; void packetParser(const char* p, int len, int offset, bool uncompress, uint16_t* qtype=0, uint16_t* qclass=0, unsigned int* consumed=0); static std::string escapeLabel(const std::string& orig); diff --git a/pdns/test-dnsname_cc.cc b/pdns/test-dnsname_cc.cc index 547ab3238..a457a9e12 100644 --- a/pdns/test-dnsname_cc.cc +++ b/pdns/test-dnsname_cc.cc @@ -410,5 +410,21 @@ BOOST_AUTO_TEST_CASE(test_compression_loop1) { // Compression loop (pointer loop BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 0, true), std::range_error); } +BOOST_AUTO_TEST_CASE(test_compression_loop2) { // Compression loop (deep recursion) + + int i; + string name("\x00\xc0\x00", 3); + for (i=0; i<98; ++i) { + name.append( 1, ((i >> 7) & 0xff) | 0xc0); + name.append( 1, ((i << 1) & 0xff) | 0x01); + } + BOOST_CHECK_NO_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true)); + + ++i; + name.append( 1, ((i >> 7) & 0xff) | 0xc0); + name.append( 1, ((i << 1) & 0xff) | 0x01); + + BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true), std::range_error); +} BOOST_AUTO_TEST_SUITE_END()