]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Include (with precautions) offending data in messages about too long a label.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 26 Sep 2022 07:29:11 +0000 (09:29 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 26 Sep 2022 07:52:05 +0000 (09:52 +0200)
Fixes #12014

pdns/dnsname.cc
pdns/dnsname.hh

index 22e2cf9f5774ac2cebba0bc49210f0f8cc574de7..544197551a5847b60b3f431940f2db27946e02bb 100644 (file)
@@ -41,6 +41,19 @@ std::ostream & operator<<(std::ostream &os, const DNSName& d)
   return os <<d.toLogString();
 }
 
+void DNSName::throwSafeRangeError(const std::string& msg, const char* buf, size_t length)
+{
+  std::string dots;
+  const size_t maxDNSNameLength = 255; // Maybe this should be a symbol in DNSName itself
+  if (length > maxDNSNameLength) {
+    length = maxDNSNameLength;
+    dots = "...";
+  }
+  std::string label;
+  DNSName::appendEscapedLabel(label, buf, length);
+  throw std::range_error(msg + label + dots);
+}
+
 DNSName::DNSName(const char* p, size_t length)
 {
   if(p[0]==0 || (p[0]=='.' && p[1]==0)) {
@@ -55,7 +68,7 @@ DNSName::DNSName(const char* p, size_t length)
       for(auto iter = pbegin; iter != pend; ) {
         lenpos = d_storage.size();
         if(*iter=='.')
-          throw std::runtime_error("Found . in wrong position in DNSName "+string(p));
+          throwSafeRangeError("Found . in wrong position in DNSName: ", p, length);
         d_storage.append(1, (char)0);
         labellen=0;
         auto begiter=iter;
@@ -66,10 +79,10 @@ DNSName::DNSName(const char* p, size_t length)
         if(iter != pend)
           ++iter;
         if(labellen > 63)
-          throw std::range_error("label too long to append");
+          throwSafeRangeError("label too long to append: ", p, length);
 
         if(iter-pbegin > 254) // reserve two bytes, one for length and one for the root label
-          throw std::range_error("name too long to append");
+          throwSafeRangeError("name too long to append: ", p, length);
 
         d_storage[lenpos]=labellen;
       }
@@ -78,7 +91,7 @@ DNSName::DNSName(const char* p, size_t length)
     else {
       d_storage=segmentDNSNameRaw(p, length);
       if(d_storage.size() > 255) {
-        throw std::range_error("name too long");
+        throwSafeRangeError("name too long: ", p, length);
       }
     }
   }
index 60db083daf209301028e0998b3e49539762b3114..63bf40e22dbedaab0dfcb0871d6e5e16caad3532 100644 (file)
@@ -149,7 +149,7 @@ public:
   DNSName& operator+=(const DNSName& rhs)
   {
     if(d_storage.size() + rhs.d_storage.size() > 256) // one extra byte for the second root label
-      throw std::range_error("name too long");
+      throwSafeRangeError("name too long", rhs.d_storage.data(), rhs.d_storage.size());
     if(rhs.empty())
       return *this;
 
@@ -217,6 +217,7 @@ private:
   void packetParser(const char* p, int len, int offset, bool uncompress, uint16_t* qtype, uint16_t* qclass, unsigned int* consumed, int depth, uint16_t minOffset);
   static void appendEscapedLabel(std::string& appendTo, const char* orig, size_t len);
   static std::string unescapeLabel(const std::string& orig);
+  static void throwSafeRangeError(const std::string& msg, const char* buf, size_t length);
 };
 
 size_t hash_value(DNSName const& d);