$NetBSD: patch-CVE-2014-8601,v 1.1 2014/12/11 20:18:17 roy Exp $

Upstream backported fix for CVE-2014-8601

commit 62d189c81359c70821523d7ba9831d0f6e57b012
Author: Your Name <you@example.com>
Date:   Tue Dec 2 08:50:41 2014 +0000

    backport query limiter to 3.3

diff --git pdns_recursor.cc pdns_recursor.cc
index 0f9b08f..3bb71e0 100644
--- pdns_recursor.cc
+++ pdns_recursor.cc
@@ -522,7 +522,14 @@ void startDoResolve(void *p)
     bool variableAnswer = false;
     // if there is a PowerDNSLua active, and it 'took' the query in preResolve, we don't launch beginResolve
     if(!t_pdl->get() || !(*t_pdl)->preresolve(dc->d_remote, g_listenSocketsAddresses[dc->d_socket], dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer)) {
-       res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret);
+      try {
+        res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret);
+      }
+      catch(ImmediateServFailException &e) {
+        L<<Logger::Error<<"Sending SERVFAIL during resolve of '"<<dc->d_mdp.d_qname<<"' because: "<<e.reason<<endl;
+
+        res = RCode::ServFail;
+      }
 
       if(t_pdl->get()) {
         if(res == RCode::NXDomain)
diff --git a/syncres.cc b/syncres.cc
index 4b05acf..08b2930 100644
--- syncres.cc
+++ syncres.cc
@@ -874,6 +874,7 @@ int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth,
           }
           else {
             s_outqueries++; d_outqueries++;
+            if(d_outqueries > 50) throw ImmediateServFailException("more than 50 queries sent while resolving "+qname);
           TryTCP:
             if(doTCP) {
               LOG<<prefix<<qname<<": using TCP with "<< remoteIP->toStringWithPort() <<endl;
diff --git a/syncres.hh b/syncres.hh
index e3249d2..6c151e0 100644
--- syncres.hh
+++ syncres.hh
@@ -502,6 +502,13 @@ private:
   static AtomicCounter s_currentConnections; //!< total number of current TCP connections
 };
 
+class ImmediateServFailException
+{
+public:
+  ImmediateServFailException(string r){reason=r;};
+
+  string reason; //! Print this to tell the user what went wrong
+};
 
 struct RemoteKeeper
 {
