Skip to content

Commit fcbe2e6

Browse files
amccalibCopilot
andauthored
Fix HC_CALL use-after-free in WinHttpConnection (#929)
WinHttpConnection stored m_call as a raw non-owning HCCallHandle. After complete_task() calls XAsyncComplete(), the caller may close the HC_CALL, but outstanding WinHttp callbacks (e.g. WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) still access m_call for trace logging, causing a use-after-free. Fix: take a refcount on m_call via HCHttpCallDuplicateHandle in the constructor and release it with HCHttpCallCloseHandle in the destructor, after WinHttp handles are closed. This matches the existing ownership pattern used for m_websocketCall. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2e2f704 commit fcbe2e6

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

Source/HTTP/WinHttp/winhttp_connection.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ WinHttpConnection::WinHttpConnection(
3535
XPlatSecurityInformation&& securityInformation
3636
) :
3737
m_hSession{ hSession },
38-
m_call{ call },
38+
m_call{ HCHttpCallDuplicateHandle(call) },
3939
m_proxyType{ proxyType },
4040
m_securityInformation{ std::move(securityInformation) },
4141
m_winHttpWebSocketExports{ WinHttpProvider::GetWinHttpWebSocketExports() }
@@ -70,6 +70,8 @@ WinHttpConnection::~WinHttpConnection()
7070
{
7171
WinHttpCloseHandle(m_hConnection);
7272
}
73+
74+
HCHttpCallCloseHandle(m_call);
7375
}
7476

7577
Result<std::shared_ptr<WinHttpConnection>> WinHttpConnection::Initialize(

Source/HTTP/WinHttp/winhttp_connection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class WinHttpConnection : public std::enable_shared_from_this<WinHttpConnection>
283283
HINTERNET m_hConnection = nullptr;
284284
HINTERNET m_hRequest = nullptr;
285285

286-
HCCallHandle m_call; // non-owning
286+
HCCallHandle m_call; // ref-counted, released in destructor
287287
Uri m_uri;
288288
XAsyncBlock* m_asyncBlock = nullptr; // non-owning
289289
XPlatSecurityInformation const m_securityInformation{};

0 commit comments

Comments
 (0)