From 10ae7b37384ae6948fc7a8fa5f282377fe14db44 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 26 Sep 2022 09:29:11 +0200 Subject: [PATCH] Include (with precautions) offending data in messages about too long a label. Fixes #12014 --- pdns/dnsname.cc | 21 +++++++++++++++++---- pdns/dnsname.hh | 3 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pdns/dnsname.cc b/pdns/dnsname.cc index 22e2cf9f57..544197551a 100644 --- a/pdns/dnsname.cc +++ b/pdns/dnsname.cc @@ -41,6 +41,19 @@ std::ostream & operator<<(std::ostream &os, const DNSName& d) return os < 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); } } } diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index 60db083daf..63bf40e22d 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -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); -- 2.47.2