Browse Source

Limit CNAME chains to 16, to avoid the possibility of an infinite CNAME loop

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1301 e5f2f494-b856-4b98-b285-d166d9295462
Evan Hunt 15 years ago
parent
commit
cd83054cc5

+ 4 - 0
src/lib/auth/data_source.cc

@@ -128,6 +128,10 @@ chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset)
         return;
     }
 
+    if (q.tooMany()) {
+        return;
+    }
+
     q.tasks().push(QueryTaskPtr(
                        new QueryTask(dynamic_cast<const generic::CNAME&>
                                      (it->getCurrent()).getCname(),

+ 1 - 0
src/lib/auth/query.cc

@@ -102,6 +102,7 @@ Query::Query(Message& m, bool dnssec) :
     qname_ = &question->getName();
     qclass_ = &question->getClass();
     qtype_ = &question->getType();
+    restarts_ = 0;
 
     querytasks_.push(QueryTaskPtr(new QueryTask(*qname_, *qclass_, *qtype_,
                                                 Section::ANSWER())));

+ 11 - 0
src/lib/auth/query.h

@@ -204,6 +204,14 @@ public:
     Status status() const { return status_; }
     void setStatus(Status s) { status_ = s; }
 
+    // Limit CNAME chains to 16 per query, to avoid loops
+    inline bool tooMany() {
+        if (++restarts_ > MAX_RESTARTS) {
+            return (true);
+        }
+        return (false);
+    }
+
 private:
     Status status_;
 
@@ -216,6 +224,9 @@ private:
 
     bool want_additional_;
     bool want_dnssec_;
+
+    static const int MAX_RESTARTS = 16;
+    int restarts_;
 };
 
 }

+ 2 - 3
src/lib/auth/tests/datasrc_unittest.cc

@@ -473,9 +473,8 @@ TEST_F(DataSrcTest, DS) {
 }
 
 TEST_F(DataSrcTest, CNAMELoop) {
-    // This should not make the process hang
-    //createAndProcessQuery(msg, Name("loop1.example.com"), RRClass::IN(),
-    //                    RRType::A());
+    createAndProcessQuery(msg, Name("loop1.example.com"), RRClass::IN(),
+                          RRType::A());
 }
 
 TEST_F(DataSrcTest, Nsec3Hash) {