VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Dlgcode.c
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2023-07-15 02:59:13 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2023-07-15 02:59:13 +0200
commit7ada94d36be07f693d94315ae80701251a3685e8 (patch)
tree6a43194140c043d724a92774726a8613052d9a79 /src/Common/Dlgcode.c
parent49fff71d0a6d41840e16d5efed748c73486a721e (diff)
downloadVeraCrypt-7ada94d36be07f693d94315ae80701251a3685e8.tar.gz
VeraCrypt-7ada94d36be07f693d94315ae80701251a3685e8.zip
Windows: enhance secure desktop handling to try to workaround Windows 11 issue
Several enhancements implemented: - replace CreateThread by _beginthreadex to avoid potential issues when using C runtime - use an event to notify monitoring thread to stop instead of a volatile boolean - perform switch to the regular desktop in the main thread and not in the secure desktop thread
Diffstat (limited to 'src/Common/Dlgcode.c')
-rw-r--r--src/Common/Dlgcode.c79
1 files changed, 49 insertions, 30 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 1717c7db..df5d6355 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -14085,13 +14085,14 @@ typedef struct
DLGPROC lpDialogFunc;
LPARAM dwInitParam;
INT_PTR retValue;
+ BOOL bDlgDisplayed; // set to TRUE if the dialog was displayed on secure desktop
} SecureDesktopThreadParam;
typedef struct
{
LPCWSTR szVCDesktopName;
HDESK hVcDesktop;
- volatile BOOL* pbStopMonitoring;
+ HANDLE hStopEvent; // event to signal when to stop monitoring
} SecureDesktopMonitoringThreadParam;
#define SECUREDESKTOP_MONOTIR_PERIOD 500
@@ -14103,11 +14104,12 @@ static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadPara
SecureDesktopMonitoringThreadParam* pMonitorParam = (SecureDesktopMonitoringThreadParam*) lpThreadParameter;
if (pMonitorParam)
{
- volatile BOOL* pbStopMonitoring = pMonitorParam->pbStopMonitoring;
+ HANDLE hStopEvent = pMonitorParam->hStopEvent;
LPCWSTR szVCDesktopName = pMonitorParam->szVCDesktopName;
HDESK hVcDesktop = pMonitorParam->hVcDesktop;
- while (!*pbStopMonitoring)
+ // loop until the stop event is signaled
+ while (WaitForSingleObject (hStopEvent, SECUREDESKTOP_MONOTIR_PERIOD) == WAIT_TIMEOUT)
{
// check that our secure desktop is still the input desktop
// otherwise, switch to it
@@ -14135,22 +14137,18 @@ static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadPara
if (bPerformSwitch)
SwitchDesktop (hVcDesktop);
-
- Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
}
}
return 0;
}
-static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter)
+static unsigned int __stdcall SecureDesktopThread( LPVOID lpThreadParameter )
{
- volatile BOOL bStopMonitoring = FALSE;
HANDLE hMonitoringThread = NULL;
unsigned int monitoringThreadID = 0;
SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter;
SecureDesktopMonitoringThreadParam monitorParam;
- HDESK hOriginalDesk = GetThreadDesktop (GetCurrentThreadId ());
BOOL bNewDesktopSet = FALSE;
// wait for SwitchDesktop to succeed before using it for current thread
@@ -14158,38 +14156,48 @@ static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter)
{
if (SwitchDesktop (pParam->hDesk))
{
- bNewDesktopSet = TRUE;
break;
}
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
}
+ bNewDesktopSet = SetThreadDesktop (pParam->hDesk);
+
if (bNewDesktopSet)
{
- SetThreadDesktop (pParam->hDesk);
-
// create the thread that will ensure that VeraCrypt secure desktop has always user input
- monitorParam.szVCDesktopName = pParam->szDesktopName;
- monitorParam.hVcDesktop = pParam->hDesk;
- monitorParam.pbStopMonitoring = &bStopMonitoring;
- hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID);
- }
+ // this is done only if the stop event is created successfully
+ HANDLE hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (hStopEvent)
+ {
+ monitorParam.szVCDesktopName = pParam->szDesktopName;
+ monitorParam.hVcDesktop = pParam->hDesk;
+ monitorParam.hStopEvent = hStopEvent;
+ hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID);
+ }
- pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName,
- NULL, pParam->lpDialogFunc, pParam->dwInitParam);
+ pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName,
+ NULL, pParam->lpDialogFunc, pParam->dwInitParam);
- if (hMonitoringThread)
- {
- bStopMonitoring = TRUE;
+ if (hMonitoringThread)
+ {
+ // notify the monitoring thread to stop
+ SetEvent(hStopEvent);
- WaitForSingleObject (hMonitoringThread, INFINITE);
- CloseHandle (hMonitoringThread);
- }
+ WaitForSingleObject (hMonitoringThread, INFINITE);
+ CloseHandle (hMonitoringThread);
+ }
- if (bNewDesktopSet)
+ if (hStopEvent)
+ {
+ CloseHandle (hStopEvent);
+ }
+
+ pParam->bDlgDisplayed = TRUE;
+ }
+ else
{
- SetThreadDesktop (hOriginalDesk);
- SwitchDesktop (hOriginalDesk);
+ pParam->bDlgDisplayed = FALSE;
}
return 0;
@@ -14249,6 +14257,7 @@ INT_PTR SecureDesktopDialogBoxParam(
map<DWORD, BOOL> ctfmonBeforeList, ctfmonAfterList;
DWORD desktopAccess = DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS;
HDESK hSecureDesk;
+ HDESK hOriginalDesk = GetThreadDesktop (GetCurrentThreadId());
HDESK hInputDesk = NULL;
@@ -14280,8 +14289,10 @@ INT_PTR SecureDesktopDialogBoxParam(
param.lpDialogFunc = lpDialogFunc;
param.dwInitParam = dwInitParam;
param.retValue = 0;
+ param.bDlgDisplayed = FALSE;
- HANDLE hThread = ::CreateThread (NULL, 0, SecureDesktopThread, (LPVOID) &param, 0, NULL);
+ // use _beginthreadex instead of CreateThread because lpDialogFunc may be using the C runtime library
+ HANDLE hThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopThread, (LPVOID) &param, 0, NULL);
if (hThread)
{
StringCbCopy(SecureDesktopName, sizeof (SecureDesktopName), szDesktopName);
@@ -14289,8 +14300,15 @@ INT_PTR SecureDesktopDialogBoxParam(
WaitForSingleObject (hThread, INFINITE);
CloseHandle (hThread);
- retValue = param.retValue;
- bSuccess = TRUE;
+ if (param.bDlgDisplayed)
+ {
+ // dialog box was indeed displayed in Secure Desktop
+ retValue = param.retValue;
+ bSuccess = TRUE;
+ }
+
+ // switch back to original desktop
+ SwitchDesktop (hOriginalDesk);
}
CloseDesktop (hSecureDesk);
@@ -14311,6 +14329,7 @@ INT_PTR SecureDesktopDialogBoxParam(
}
}
+ CloseDesktop(hOriginalDesk);
burn (szDesktopName, sizeof (szDesktopName));
}
}