From 38808ad999a8df631c4d76d4ce573d283edfd261 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Sat, 14 Jun 2025 13:59:53 +0000 Subject: Bug [7c2716733a] - use after free on Windows event handle --- win/tclWinInt.h | 3 +-- win/tclWinPipe.c | 26 +++----------------------- win/tclWinSerial.c | 3 +-- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/win/tclWinInt.h b/win/tclWinInt.h index 2c702fb..3ba3c57 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -76,7 +76,6 @@ typedef struct TclPipeThreadInfo { * used as signal to stop (state set to -1) */ volatile LONG state; /* Indicates current state of the thread */ void *clientData; /* Referenced data of the main thread */ - HANDLE evWakeUp; /* Optional wake-up event worker set by shutdown */ } TclPipeThreadInfo; /* If pipe-workers will use some tcl subsystem, we can use Tcl_Alloc without @@ -101,7 +100,7 @@ enum PipeWorkerStates { MODULE_SCOPE TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr, - void *clientData, HANDLE wakeEvent); + void *clientData); MODULE_SCOPE int TclPipeThreadWaitForSignal( TclPipeThreadInfo **pipeTIPtr); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 2aa6d98..a2b630a 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1817,8 +1817,7 @@ TclpCreateCommandChannel( infoPtr->readable = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, - TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr, infoPtr->readable), - 0, NULL); + TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr), 0, NULL); SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; } else { @@ -1832,8 +1831,7 @@ TclpCreateCommandChannel( infoPtr->writable = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, - TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, infoPtr->writable), - 0, NULL); + TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, NULL); SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; } else { @@ -3301,8 +3299,7 @@ TclpOpenTemporaryFile( TclPipeThreadInfo * TclPipeThreadCreateTI( TclPipeThreadInfo **pipeTIPtr, - void *clientData, - HANDLE wakeEvent) + void *clientData) { TclPipeThreadInfo *pipeTI; #ifndef _PTI_USE_CKALLOC @@ -3313,7 +3310,6 @@ TclPipeThreadCreateTI( pipeTI->evControl = CreateEventW(NULL, FALSE, FALSE, NULL); pipeTI->state = PTI_STATE_IDLE; pipeTI->clientData = clientData; - pipeTI->evWakeUp = wakeEvent; return (*pipeTIPtr = pipeTI); } @@ -3341,14 +3337,11 @@ TclPipeThreadWaitForSignal( TclPipeThreadInfo *pipeTI = *pipeTIPtr; LONG state; DWORD waitResult; - HANDLE wakeEvent; if (!pipeTI) { return 0; } - wakeEvent = pipeTI->evWakeUp; - /* * Wait for the main thread to signal before attempting to do the work. */ @@ -3408,11 +3401,6 @@ TclPipeThreadWaitForSignal( if (state != PTI_STATE_STOP) { *pipeTIPtr = NULL; - } else { - pipeTI->evWakeUp = NULL; - } - if (wakeEvent) { - SetEvent(wakeEvent); } return 0; } @@ -3446,7 +3434,6 @@ TclPipeThreadStopSignal( return 1; } evControl = pipeTI->evControl; - pipeTI->evWakeUp = wakeEvent; state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_STOP, PTI_STATE_IDLE); switch (state) { @@ -3510,7 +3497,6 @@ TclPipeThreadStop( } pipeTI = *pipeTIPtr; evControl = pipeTI->evControl; - pipeTI->evWakeUp = NULL; /* * Try to sane stop the pipe worker, corresponding its current state @@ -3662,9 +3648,6 @@ TclPipeThreadStop( *pipeTIPtr = NULL; if (pipeTI) { - if (pipeTI->evWakeUp) { - SetEvent(pipeTI->evWakeUp); - } CloseHandle(pipeTI->evControl); #ifndef _PTI_USE_CKALLOC free(pipeTI); @@ -3713,9 +3696,6 @@ TclPipeThreadExit( state = InterlockedExchange(&pipeTI->state, PTI_STATE_DOWN); if (state == PTI_STATE_STOP) { CloseHandle(pipeTI->evControl); - if (pipeTI->evWakeUp) { - SetEvent(pipeTI->evWakeUp); - } #ifndef _PTI_USE_CKALLOC free(pipeTI); #else diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index 690183c..48baaa8 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -1506,8 +1506,7 @@ TclWinOpenSerialChannel( infoPtr->osWrite.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); infoPtr->evWritable = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread, - TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, - infoPtr->evWritable), 0, NULL); + TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, NULL); } Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto"); -- cgit v0.12