]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: backport CVE-2024-25583 to rel/rec-5.0.4-branch
authorOtto Moerbeek <otto@drijf.net>
Tue, 9 Apr 2024 07:31:59 +0000 (09:31 +0200)
committerOtto Moerbeek <otto@drijf.net>
Tue, 9 Apr 2024 08:25:56 +0000 (10:25 +0200)
A name can be present already when building the cname chain.

pdns/recursordist/syncres.cc
pdns/recursordist/test-syncres_cc1.cc

index e442842a4a5333d10a121501c6e75bd5135cd506..3e16befcc4fbe3edb4a16cf8408953ca33303839 100644 (file)
@@ -4390,7 +4390,10 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string&
         break;
       }
       initial = cnameIt->second;
-      wildcardCandidates.emplace(initial, false);
+      if (!wildcardCandidates.emplace(initial, false).second) {
+        // CNAME Loop
+        break;
+      }
     }
   }
 
index 372f07873fb5737db4871c9f6f68371e7e6834a6..42d9252beddffaa3be2cb70df2fa719569a19efd 100644 (file)
@@ -1632,6 +1632,54 @@ BOOST_AUTO_TEST_CASE(test_cname_loop)
   }
 }
 
+BOOST_AUTO_TEST_CASE(test_cname_loop_forwarder)
+{
+  std::unique_ptr<SyncRes> resolver;
+  initSR(resolver);
+
+  primeHints();
+
+  size_t count = 0;
+  const DNSName target("cname.powerdns.com.");
+  const DNSName cname1("cname1.cname.powerdns.com.");
+  const DNSName cname2("cname2.cname.powerdns.com.");
+
+  SyncRes::AuthDomain ad;
+  const std::vector<ComboAddress> forwardedNSs{ComboAddress("192.0.2.42:53")};
+  ad.d_rdForward = true;
+  ad.d_servers = forwardedNSs;
+  (*SyncRes::t_sstorage.domainmap)[target] = ad;
+
+  resolver->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
+    count++;
+
+    if (isRootServer(address)) {
+
+      setLWResult(res, 0, false, false, true);
+      addRecordToLW(res, domain, QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
+      addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
+      return LWResult::Result::Success;
+    }
+    if (address == ComboAddress("192.0.2.42:53")) {
+
+      if (domain == target) {
+        setLWResult(res, 0, true, false, false);
+        addRecordToLW(res, domain, QType::CNAME, cname1.toString());
+        addRecordToLW(res, cname1, QType::CNAME, cname2.toString());
+        addRecordToLW(res, cname2, QType::CNAME, domain.toString());
+        return LWResult::Result::Success;
+      }
+
+      return LWResult::Result::Success;
+    }
+
+    return LWResult::Result::Timeout;
+  });
+
+  vector<DNSRecord> ret;
+  BOOST_REQUIRE_THROW(resolver->beginResolve(target, QType(QType::A), QClass::IN, ret), ImmediateServFailException);
+}
+
 BOOST_AUTO_TEST_CASE(test_cname_long_loop)
 {
   std::unique_ptr<SyncRes> sr;