From 373b0b424ddf5ba1e456741a8ec3e3c2d9b4c932 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Tue, 9 Aug 2022 15:15:46 -0700 Subject: [PATCH] Fixed memory leaks with Metadata string on Windows IPC socket, and overlapped data structure --- microscript/ILibDuktape_net.c | 15 +++++++++++---- microstack/ILibParsers.c | 13 +++++++++---- microstack/ILibParsers.h | 4 +++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/microscript/ILibDuktape_net.c b/microscript/ILibDuktape_net.c index ccff9d1..5a03a77 100644 --- a/microscript/ILibDuktape_net.c +++ b/microscript/ILibDuktape_net.c @@ -39,6 +39,11 @@ limitations under the License. #include #endif +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE) +#define _CRTDBG_MAP_ALLOC +#include +#endif + #ifdef OLDSSL #define TLS_method SSLv23_method #endif @@ -1137,6 +1142,7 @@ void ILibDuktape_net_server_IPC_EndSink(ILibDuktape_DuplexStream *stream, void * ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user; if (winIPC->mServer != NULL && winIPC->mPipeHandle == NULL) { return; } // Already Closed winIPC->endCalled = 1; + if (winIPC->metadata != NULL) { ILibMemory_Free(winIPC->metadata); winIPC->metadata = NULL; } if (winIPC->reservedState != NULL) { ILibChain_WaitHandle_DestroySavedState(winIPC->mChain, winIPC->reservedState); @@ -1145,8 +1151,8 @@ void ILibDuktape_net_server_IPC_EndSink(ILibDuktape_DuplexStream *stream, void * else { // We probably aren't paused, so we need to remove our wait handles - if (winIPC->read_overlapped.hEvent != NULL) { ILibChain_RemoveWaitHandle(winIPC->mChain, winIPC->read_overlapped.hEvent); } - if (winIPC->write_overlapped.hEvent != NULL) { ILibChain_RemoveWaitHandle(winIPC->mChain, winIPC->write_overlapped.hEvent); } + if (winIPC->read_overlapped.hEvent != NULL) { ILibChain_RemoveWaitHandleEx(winIPC->mChain, winIPC->read_overlapped.hEvent, 1); } + if (winIPC->write_overlapped.hEvent != NULL) { ILibChain_RemoveWaitHandleEx(winIPC->mChain, winIPC->write_overlapped.hEvent, 1); } } if (winIPC->mPipeHandle != NULL) { @@ -1224,18 +1230,19 @@ duk_ret_t ILibDuktape_net_server_IPC_ConnectSink_Finalizer(duk_context *ctx) } if (winIPC->read_overlapped.hEvent != NULL) { - ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), winIPC->read_overlapped.hEvent); + ILibChain_RemoveWaitHandleEx(duk_ctx_chain(ctx), winIPC->read_overlapped.hEvent, 1); CloseHandle(winIPC->read_overlapped.hEvent); winIPC->read_overlapped.hEvent = NULL; } if (winIPC->write_overlapped.hEvent != NULL) { - ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), winIPC->write_overlapped.hEvent); + ILibChain_RemoveWaitHandleEx(duk_ctx_chain(ctx), winIPC->write_overlapped.hEvent, 1); CloseHandle(winIPC->write_overlapped.hEvent); winIPC->write_overlapped.hEvent = NULL; } if (winIPC->buffer != NULL) { free(winIPC->buffer); } + if (winIPC->metadata != NULL) { ILibMemory_Free(winIPC->metadata); winIPC->metadata = NULL; } } return(0); } diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 2e1349a..41a7677 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -2199,6 +2199,7 @@ int ILibChain_WindowsSelect(void *chain, fd_set *readset, fd_set *writeset, fd_s if (((ILibBaseChain*)chain)->currentHandle != NULL && ILibMemory_CanaryOK(info)) { ILIBLOGMESSAGEX2(LOGEX_OVERLAPPED_IO, " * ILibChain_WindowsSelect(%p) [REMOVED]", ((ILibBaseChain*)chain)->currentHandle); + info->user = NULL; ILibLinkedList_Remove(info->node); } else @@ -3930,7 +3931,7 @@ void __stdcall ILibChain_RemoveWaitHandle_APC(ULONG_PTR u) { ILibBaseChain *chain = (ILibBaseChain*)((void**)u)[0]; HANDLE h = (HANDLE)((void**)u)[1]; - + int clean = (int)(intptr_t)((void**)u)[2]; void *node = ILibLinkedList_GetNode_Search(chain->auxSelectHandles, NULL, h); if (node != NULL) { @@ -3943,17 +3944,20 @@ void __stdcall ILibChain_RemoveWaitHandle_APC(ULONG_PTR u) chain->currentHandle = NULL; chain->currentInfo = NULL; } ILibChain_WaitHandleInfo *info = (ILibChain_WaitHandleInfo*)ILibMemory_Extra(node); + if (clean != 0) { ILibMemory_Free(info->user); } ILibLinkedList_Remove(node); chain->UnblockFlag = 1; } } -void ILibChain_RemoveWaitHandle(void *chain, HANDLE h) + +void ILibChain_RemoveWaitHandleEx(void *chain, HANDLE h, int clean) { if (ILibIsRunningOnChainThread(chain)) { - void *tmp[2]; + void *tmp[3]; tmp[0] = chain; tmp[1] = h; + tmp[2] = (void*)(intptr_t)clean; ILibChain_RemoveWaitHandle_APC((ULONG_PTR)tmp); } else @@ -3962,9 +3966,10 @@ void ILibChain_RemoveWaitHandle(void *chain, HANDLE h) // We must dispatch an APC to remove the wait handle, // because we can't change the wait list during a WaitForMultipleObjectsEx() call // - void **tmp = (void**)ILibMemory_SmartAllocate(2 * sizeof(void*)); + void **tmp = (void**)ILibMemory_SmartAllocate(3 * sizeof(void*)); tmp[0] = chain; tmp[1] = h; + tmp[2] = (void*)(intptr_t)clean; QueueUserAPC((PAPCFUNC)ILibChain_RemoveWaitHandle_APC, ILibChain_GetMicrostackThreadHandle(chain), (ULONG_PTR)tmp); } } diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index b7903b9..604fcb5 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -1113,7 +1113,9 @@ int ILibIsRunningOnChainThread(void* chain); void ILibChain_WaitHandle_UpdateMetadata(void *chain, HANDLE h, char *metadata); void ILibChain_AddWaitHandleEx(void *chain, HANDLE h, int msTIMEOUT, ILibChain_WaitHandleHandler handler, void *user, char *metadata); #define ILibChain_AddWaitHandle(chain, h, msTIMEOUT, handler, user) ILibChain_AddWaitHandleEx(chain, h, msTIMEOUT, handler, user, ILibChain_MetaData(__FILE__, __LINE__)) - void ILibChain_RemoveWaitHandle(void *chain, HANDLE h); + #define ILibChain_RemoveWaitHandle(chain, h) ILibChain_RemoveWaitHandleEx(chain, h, 0) + void ILibChain_RemoveWaitHandleEx(void *chain, HANDLE h, int clean); + void ILibChain_ReadEx2(void *chain, HANDLE h, OVERLAPPED *p, char *buffer, DWORD bufferLen, ILibChain_ReadEx_Handler handler, void *user, char *metadata); #define ILibChain_ReadEx(chain, h, overlapped, buffer, bufferLen, handler, user) ILibChain_ReadEx2(chain, h, overlapped, buffer, bufferLen, handler, user, ILibChain_MetaData(__FILE__, __LINE__)) ILibTransport_DoneState ILibChain_WriteEx2(void *chain, HANDLE h, OVERLAPPED *p, char *buffer, DWORD bufferLen, ILibChain_WriteEx_Handler handler, void *user, char *metadata);