]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix a crash when a DoH responses map is updated at runtime 9934/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 14:37:52 +0000 (15:37 +0100)
pdns/dnsdist-lua.cc
pdns/dnsdistdist/doh.cc
pdns/doh.hh

index 97a748ac44815bd33410b1ebcae72492c1f1a1de..e8049beb345d33b7365db44cb5b26b4645d55c9e 100644 (file)
@@ -2192,11 +2192,11 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
     luaCtx.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 b1a0c4c02759d08c9d01deba801643dc6e5a39b1..919db49bcfce6c4aad230cf056f5b9a69738c142 100644 (file)
@@ -843,11 +843,16 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req)
     // would be nice to be able to use a pdns_string_view there,
     // but regex (called by matches() internally) requires a null-terminated string
     string path(req->path.base, req->path.len);
-    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 5327457d7fbe24bc7c14d4c81475c6c2822057ac..10ed9a1b6d224bcdcabb8630a6d88f6a59813116 100644 (file)
@@ -71,7 +71,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"};