From 20d080f24d7a9a70ad05aa093c9d7a68d0adc966 Mon Sep 17 00:00:00 2001 From: Tamir Suliman Date: Sat, 6 Jun 2026 13:32:38 +0200 Subject: [PATCH] Fix #6 - hPipeWrite handle leak when CreateProcess fails In both RunCommandAndGetOutput and RunCommandAndGetOutputWithTimeout, hPipeWrite was only closed inside the CreateProcess success branch. On failure the write handle leaked, consuming a kernel handle slot on every failed invocation. Captured the CreateProcess return value into a bool and moved CloseHandle(hPipeWrite) to run unconditionally after the call, before the success check, which is the standard Windows pipe pattern. Fixes #6 --- FIDO2.1 Manager.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/FIDO2.1 Manager.cpp b/FIDO2.1 Manager.cpp index 2d552e1..8c047ec 100644 --- a/FIDO2.1 Manager.cpp +++ b/FIDO2.1 Manager.cpp @@ -83,12 +83,14 @@ std::vector RunCommandAndGetOutput(const std::wstring& command) { PROCESS_INFORMATION pi = { 0 }; - if (CreateProcess( + bool processCreated = CreateProcess( NULL, const_cast(command.c_str()), - NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { - CloseHandle(hPipeWrite); + NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi) != 0; + CloseHandle(hPipeWrite); + + if (processCreated) { char buffer[1024]; DWORD bytesRead; while (ReadFile(hPipeRead, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead > 0) { @@ -636,12 +638,14 @@ std::vector RunCommandAndGetOutputWithTimeout(const std::wstring& PROCESS_INFORMATION pi = { 0 }; - if (CreateProcess( + bool processCreated = CreateProcess( NULL, const_cast(command.c_str()), - NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { - CloseHandle(hPipeWrite); + NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi) != 0; + CloseHandle(hPipeWrite); + + if (processCreated) { // Wait for the process to finish or timeout DWORD waitResult = WaitForSingleObject(pi.hProcess, timeoutMs); if (waitResult == WAIT_TIMEOUT) {