]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix a crash when processing timeouts for incoming DoH queries 15482/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 28 Apr 2025 10:41:00 +0000 (12:41 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 29 Apr 2025 08:09:01 +0000 (10:09 +0200)
This commit fixes a double-free triggered by an exception being raised
while we are processing a timeout for an incoming DoH query. The exception
bypasses the call releasing the smart pointer, and thus the destructor
is called when we reach the end of the function since we own the smart
pointer, but unfortunately it has already been destroyed by the function
that raised the exception. The fix is to release the pointer first,
then call the function, so even if an exception is raised we no longer
own the pointer, and it's clear that the function has taken ownership of it.

(cherry picked from commit 954eb1921699147b16f8bcd08029e37da3e789b9)

pdns/dnsdist-doh-common.hh

index 9d0a4669288ffe3db4aa939b76eaa1ee6b83ade7..da2db8c6185467fd03d9d7f286d33002bf46ed71 100644 (file)
@@ -235,16 +235,16 @@ struct DOHUnitInterface
   static void handleTimeout(std::unique_ptr<DOHUnitInterface> unit)
   {
     if (unit) {
-      unit->handleTimeout();
-      unit.release();
+      auto* ptr = unit.release();
+      ptr->handleTimeout();
     }
   }
 
   static void handleUDPResponse(std::unique_ptr<DOHUnitInterface> unit, PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr<DownstreamState>& ds)
   {
     if (unit) {
-      unit->handleUDPResponse(std::move(response), std::move(state), ds);
-      unit.release();
+      auto* ptr = unit.release();
+      ptr->handleUDPResponse(std::move(response), std::move(state), ds);
     }
   }