mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 02:58:02 -06:00
Windows: Implement mutex to serialize initialization across multiple VeraCrypt instances
When multiple VeraCrypt.exe instances were launched simultaneously, race conditions could occur during the WM_INITDIALOG processing phase, potentially causing application crashes or hang. This was because the initialization logic handles critical operations like mounting/unmounting volumes and processing favorite volumes that modify global system state. This commit: - Adds a named local session mutex (MainInitMutex) that serializes the WM_INITDIALOG handler - Implements proper acquisition and release of the mutex during initialization - Ensures proper cleanup of mutex resources on application exit
This commit is contained in:
@@ -187,6 +187,10 @@ static DWORD LastKnownLogicalDrives;
|
|||||||
|
|
||||||
static volatile LONG FavoriteMountOnGoing = 0;
|
static volatile LONG FavoriteMountOnGoing = 0;
|
||||||
|
|
||||||
|
|
||||||
|
const wchar_t* MainInitMutexName = L"Local\\VeraCryptMainInit_02B831C5_401D_4A0D_8CC5_98D2C4CEB5F2";
|
||||||
|
static HANDLE MainInitMutex = NULL; /* Mutex for main dialog WM_INITDIALOG */
|
||||||
|
static BOOL MainInitMutexAcquired = FALSE; /* TRUE if the main window mutex has been acquired */
|
||||||
static HANDLE TaskBarIconMutex = NULL;
|
static HANDLE TaskBarIconMutex = NULL;
|
||||||
static BOOL MainWindowHidden = FALSE;
|
static BOOL MainWindowHidden = FALSE;
|
||||||
static int pwdChangeDlgMode = PCDM_CHANGE_PASSWORD;
|
static int pwdChangeDlgMode = PCDM_CHANGE_PASSWORD;
|
||||||
@@ -202,6 +206,29 @@ static HMODULE hWtsLib = NULL;
|
|||||||
static WTSREGISTERSESSIONNOTIFICATION fnWtsRegisterSessionNotification = NULL;
|
static WTSREGISTERSESSIONNOTIFICATION fnWtsRegisterSessionNotification = NULL;
|
||||||
static WTSUNREGISTERSESSIONNOTIFICATION fnWtsUnRegisterSessionNotification = NULL;
|
static WTSUNREGISTERSESSIONNOTIFICATION fnWtsUnRegisterSessionNotification = NULL;
|
||||||
|
|
||||||
|
void AcquireMainInitMutex ()
|
||||||
|
{
|
||||||
|
if (MainInitMutex && !MainInitMutexAcquired)
|
||||||
|
{
|
||||||
|
DWORD dwWaitResult;
|
||||||
|
dwWaitResult = WaitForSingleObject (MainInitMutex, INFINITE);
|
||||||
|
if (dwWaitResult == WAIT_OBJECT_0 || dwWaitResult == WAIT_ABANDONED)
|
||||||
|
{
|
||||||
|
// Mutex acquired successfully
|
||||||
|
MainInitMutexAcquired = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReleaseMainInitMutex ()
|
||||||
|
{
|
||||||
|
if (MainInitMutex && MainInitMutexAcquired)
|
||||||
|
{
|
||||||
|
ReleaseMutex (MainInitMutex);
|
||||||
|
MainInitMutexAcquired = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Used to opt-in to receive notification about power events.
|
// Used to opt-in to receive notification about power events.
|
||||||
// This is mandatory to support Windows 10 Modern Standby and Windows 8.1 Connected Standby power model.
|
// This is mandatory to support Windows 10 Modern Standby and Windows 8.1 Connected Standby power model.
|
||||||
// https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/prepare-software-for-modern-standby
|
// https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/prepare-software-for-modern-standby
|
||||||
@@ -426,6 +453,13 @@ static void localcleanup (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
RandStop (TRUE);
|
RandStop (TRUE);
|
||||||
|
|
||||||
|
if (MainInitMutex != NULL)
|
||||||
|
{
|
||||||
|
ReleaseMainInitMutex ();
|
||||||
|
CloseHandle (MainInitMutex);
|
||||||
|
MainInitMutex = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BS_SPLITBUTTON
|
#ifndef BS_SPLITBUTTON
|
||||||
@@ -7093,6 +7127,9 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||||||
bUseSecureDesktop = FALSE;
|
bUseSecureDesktop = FALSE;
|
||||||
bUseLegacyMaxPasswordLength = FALSE;
|
bUseLegacyMaxPasswordLength = FALSE;
|
||||||
|
|
||||||
|
// lock the init mutex
|
||||||
|
AcquireMainInitMutex ();
|
||||||
|
|
||||||
ResetWrongPwdRetryCount ();
|
ResetWrongPwdRetryCount ();
|
||||||
|
|
||||||
ExtractCommandLine (hwndDlg, (wchar_t *) lParam);
|
ExtractCommandLine (hwndDlg, (wchar_t *) lParam);
|
||||||
@@ -7149,7 +7186,8 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||||||
if (ComServerMode)
|
if (ComServerMode)
|
||||||
{
|
{
|
||||||
InitDialog (hwndDlg);
|
InitDialog (hwndDlg);
|
||||||
|
// unlock mutex since we are starting the COM server
|
||||||
|
ReleaseMainInitMutex ();
|
||||||
if (!ComServerMain ())
|
if (!ComServerMain ())
|
||||||
{
|
{
|
||||||
handleWin32Error (hwndDlg, SRC_POS);
|
handleWin32Error (hwndDlg, SRC_POS);
|
||||||
@@ -7532,6 +7570,8 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||||||
RegisterWtsAndPowerNotification(hwndDlg);
|
RegisterWtsAndPowerNotification(hwndDlg);
|
||||||
DoPostInstallTasks (hwndDlg);
|
DoPostInstallTasks (hwndDlg);
|
||||||
ResetCurrentDirectory ();
|
ResetCurrentDirectory ();
|
||||||
|
// unlock the init mutex
|
||||||
|
ReleaseMainInitMutex ();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -10201,6 +10241,26 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpsz
|
|||||||
AbortProcess ("NODRIVER");
|
AbortProcess ("NODRIVER");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize Main mutex */
|
||||||
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
SECURITY_DESCRIPTOR sd;
|
||||||
|
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
sa.lpSecurityDescriptor = &sd;
|
||||||
|
sa.bInheritHandle = FALSE;
|
||||||
|
|
||||||
|
// Initialize a security descriptor with a NULL DACL (everyone full access)
|
||||||
|
if (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) &&
|
||||||
|
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
|
||||||
|
{
|
||||||
|
// Use the security attributes when creating the mutex
|
||||||
|
MainInitMutex = CreateMutexW(&sa, FALSE, MainInitMutexName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If security descriptor initialization fails, fall back to default security attributes
|
||||||
|
MainInitMutex = CreateMutexW(NULL, FALSE, MainInitMutexName);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the main dialog box */
|
/* Create the main dialog box */
|
||||||
DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_MOUNT_DLG), NULL, (DLGPROC) MainDialogProc,
|
DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_MOUNT_DLG), NULL, (DLGPROC) MainDialogProc,
|
||||||
(LPARAM) lpszCommandLine);
|
(LPARAM) lpszCommandLine);
|
||||||
|
|||||||
Reference in New Issue
Block a user