From 8ad1ea499d028c28e412ea26622b801a07b3b897 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Tue, 12 Aug 2025 00:33:45 +0100 Subject: [PATCH] Windows: Avoid a double-free if a thread is terminated twice Unlikely to show up in any real code, but if an attempt is made to terminate a terminated thread we should handle this gracefully. --- Source/Windows/ARM64EC/Module.cpp | 8 +++++++- Source/Windows/WOW64/Module.cpp | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index efa9c147c..8dd677aa8 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -974,7 +974,13 @@ NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) { { std::scoped_lock Lock(ThreadCreationMutex); - Threads.erase(ThreadTID); + auto it = Threads.find(ThreadTID); + if (it == Threads.end()) { + // Thread already terminated + return STATUS_SUCCESS; + } + + Threads.erase(it); if (StatAllocHandler) { StatAllocHandler->DeallocateSlot(CPUArea.ThreadState()->ThreadStats); } diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index b8429aa58..af499065e 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -591,7 +591,13 @@ void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) { { std::scoped_lock Lock(ThreadCreationMutex); - Threads.erase(ThreadTID); + auto it = Threads.find(ThreadTID); + if (it == Threads.end()) { + // Thread already terminated + return; + } + + Threads.erase(it); if (StatAllocHandler) { StatAllocHandler->DeallocateSlot(TLS.ThreadState()->ThreadStats); }