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.
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);
}
}