]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix a crash when a DoH responses map is updated at runtime 9936/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 11 Jan 2021 14:37:52 +0000 (15:37 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 11 Jan 2021 15:09:15 +0000 (16:09 +0100)
(cherry picked from commit 312baf27f5357fae66582a8bbe937abff3c8d4fc)

pdns/dnsdist-lua.cc
pdns/dnsdistdist/doh.cc
pdns/doh.hh

index 5de7eb5991eeb3d7d0d09ef816c8b87a8c0ff943..730ebe5e26360d5849addb1ff879e20a4ed4e779 100644 (file)
@@ -2079,11 +2079,11 @@ static void setupLuaConfig(bool client, bool configCheck)
 
     g_lua.registerFunction<void(std::shared_ptr<DOHFrontend>::*)(const std::map<int, std::shared_ptr<DOHResponseMapEntry>>&)>("setResponsesMap", [](std::shared_ptr<DOHFrontend> frontend, const std::map<int, std::shared_ptr<DOHResponseMapEntry>>& map) {
         if (frontend != nullptr) {
-          std::vector<std::shared_ptr<DOHResponseMapEntry>> newMap;
-          newMap.reserve(map.size());
+          auto newMap = std::make_shared<std::vector<std::shared_ptr<DOHResponseMapEntry>>>();
+          newMap->reserve(map.size());
 
           for (const auto& entry : map) {
-            newMap.push_back(entry.second);
+            newMap->push_back(entry.second);
           }
 
           frontend->d_responsesMap = std::move(newMap);
index 24e17b000c345feb45853a45c1991e2edb8535ab..86efdf1eed44b931b8139086b71d0b222797282f 100644 (file)
@@ -824,11 +824,16 @@ try
     return 0;
   }
 
-  for (const auto& entry : dsc->df->d_responsesMap) {
-    if (entry->matches(path)) {
-      const auto& customHeaders = entry->getHeaders();
-      handleResponse(*dsc->df, req, entry->getStatusCode(), entry->getContent(), customHeaders ? *customHeaders : dsc->df->d_customResponseHeaders, std::string(), false);
-      return 0;
+  /* the responses map can be updated at runtime, so we need to take a copy of
+     the shared pointer, increasing the reference counter */
+  auto responsesMap = dsc->df->d_responsesMap;
+  if (responsesMap) {
+    for (const auto& entry : *responsesMap) {
+      if (entry->matches(path)) {
+        const auto& customHeaders = entry->getHeaders();
+        handleResponse(*dsc->df, req, entry->getStatusCode(), entry->getContent(), customHeaders ? *customHeaders : dsc->df->d_customResponseHeaders, std::string(), false);
+        return 0;
+      }
     }
   }
 
index 36d720cd427df8304ea1d223c20c0a1d847706be..87b1e1ad021c3acc332bb188df259c6c482e0270 100644 (file)
@@ -66,7 +66,7 @@ struct DOHFrontend
   }
 
   std::shared_ptr<DOHServerConfig> d_dsc{nullptr};
-  std::vector<std::shared_ptr<DOHResponseMapEntry>> d_responsesMap;
+  std::shared_ptr<std::vector<std::shared_ptr<DOHResponseMapEntry>>> d_responsesMap;
   TLSConfig d_tlsConfig;
   TLSErrorCounters d_tlsCounters;
   std::string d_serverTokens{"h2o/dnsdist"};