]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth: detect SOA cache pollution caused by broken backends 7881/head
authorKees Monshouwer <mind04@monshouwer.org>
Fri, 7 Jun 2019 07:14:29 +0000 (09:14 +0200)
committermind04 <mind04@monshouwer.org>
Fri, 7 Jun 2019 18:27:20 +0000 (20:27 +0200)
pdns/ueberbackend.cc

index 6c3aecae1276ab01373b225405efda980b13dc8c..2c3dd363b04d4ef65a7d74c325c0c494ede9d86e 100644 (file)
@@ -282,7 +282,7 @@ bool UeberBackend::getAuth(const DNSName &target, const QType& qtype, SOAData* s
   // com. We then store that and keep querying the other backends in case one
   // of them has a more specific zone but don't bother asking this specific
   // backend again for b.c.example.com., c.example.com. and example.com.
-  // If a backend has no match it may respond with an enmpty qname.
+  // If a backend has no match it may respond with an empty qname.
 
   bool found = false;
   int cstat;
@@ -330,6 +330,9 @@ bool UeberBackend::getAuth(const DNSName &target, const QType& qtype, SOAData* s
           DLOG(g_log<<Logger::Error<<"lookup: "<<shorter<<endl);
           if((*i)->getAuth(shorter, sd)) {
             DLOG(g_log<<Logger::Error<<"got: "<<sd->qname<<endl);
+            if(!shorter.isPartOf(sd->qname) && !sd->qname.empty()) {
+              throw PDNSException("getAuth() returned an SOA for the wrong zone. Zone '"+sd->qname.toLogString()+"' is not part of '"+shorter.toLogString()+"'");
+            }
             j->first = sd->qname.wirelength();
             j->second = *sd;
             if(sd->qname == shorter) {
@@ -409,6 +412,9 @@ bool UeberBackend::getSOAUncached(const DNSName &domain, SOAData &sd)
 
   for(vector<DNSBackend *>::const_iterator i=backends.begin();i!=backends.end();++i)
     if((*i)->getSOA(domain, sd)) {
+      if(domain != sd.qname) {
+        throw PDNSException("getSOA() returned an SOA for the wrong zone. Question: '"+domain.toLogString()+"', answer: '"+sd.qname.toLogString()+"'");
+      }
       if(d_cache_ttl) {
         DNSZoneRecord rr;
         rr.dr.d_name = sd.qname;