]> granicus.if.org Git - pdns/commitdiff
add redirect loop safeguard in dnsname
authorKees Monshouwer <mind04@monshouwer.org>
Mon, 4 May 2015 20:56:06 +0000 (22:56 +0200)
committermind04 <mind04@monshouwer.org>
Mon, 4 May 2015 21:48:12 +0000 (23:48 +0200)
pdns/dnsname.cc
pdns/dnsname.hh
pdns/test-dnsname_cc.cc

index 8f1bb5b0f52b62dc3176dd95d7b0417f1a1ed90f..a3d2778e9d2f97d04e99deea5dc4df816de86213 100644 (file)
@@ -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;
index f2b83a6d67beb75b4d6102d7490fd06d1fbf7fb5..de5623502c5935fd2794db0d2bd0ee60292d6815 100644 (file)
@@ -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);
index 547ab32385b8fa33d640841758a7a68fac552f17..a457a9e12f7d85d6de6cc8a609edc914ca5d36d1 100644 (file)
@@ -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()