Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -0,0 +1,270 @@
#include <winpr/crt.h>
#include <winpr/crypto.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/interlocked.h>
#include <winpr/sysinfo.h>
#include "../synch.h"
static SYNCHRONIZATION_BARRIER gBarrier;
static HANDLE gStartEvent = nullptr;
static LONG gErrorCount = 0;
#define MAX_SLEEP_MS 22
struct test_params
{
LONG threadCount;
LONG trueCount;
LONG falseCount;
DWORD loops;
DWORD flags;
};
static UINT32 prand(UINT32 max)
{
UINT32 tmp = 0;
if (max <= 1)
return 1;
if (winpr_RAND(&tmp, sizeof(tmp)) < 0)
{
// NOLINTNEXTLINE(concurrency-mt-unsafe)
exit(-1);
}
return tmp % (max - 1) + 1;
}
static DWORD WINAPI test_synch_barrier_thread(LPVOID lpParam)
{
BOOL status = FALSE;
struct test_params* p = (struct test_params*)lpParam;
InterlockedIncrement(&p->threadCount);
// printf("Thread #%03u entered.\n", tnum);
/* wait for start event from main */
if (WaitForSingleObject(gStartEvent, INFINITE) != WAIT_OBJECT_0)
{
InterlockedIncrement(&gErrorCount);
goto out;
}
// printf("Thread #%03u unblocked.\n", tnum);
for (DWORD i = 0; i < p->loops && gErrorCount == 0; i++)
{
/* simulate different execution times before the barrier */
Sleep(1 + prand(MAX_SLEEP_MS));
status = EnterSynchronizationBarrier(&gBarrier, p->flags);
// printf("Thread #%03u status: %s\n", tnum, status ? "TRUE" : "FALSE");
if (status)
InterlockedIncrement(&p->trueCount);
else
InterlockedIncrement(&p->falseCount);
}
out:
// printf("Thread #%03u leaving.\n", tnum);
return 0;
}
static BOOL TestSynchBarrierWithFlags(DWORD dwFlags, DWORD dwThreads, DWORD dwLoops)
{
BOOL rc = FALSE;
DWORD dwStatus = 0;
struct test_params p = {
.threadCount = 0, .trueCount = 0, .falseCount = 0, .loops = dwLoops, .flags = dwFlags
};
DWORD expectedTrueCount = dwLoops;
DWORD expectedFalseCount = dwLoops * (dwThreads - 1);
printf("%s: >> Testing with flags 0x%08" PRIx32 ". Using %" PRIu32
" threads performing %" PRIu32 " loops\n",
__func__, dwFlags, dwThreads, dwLoops);
HANDLE* threads = (HANDLE*)calloc(dwThreads, sizeof(HANDLE));
if (!threads)
{
printf("%s: error allocatin thread array memory\n", __func__);
return FALSE;
}
if (dwThreads > INT32_MAX)
goto fail;
if (!InitializeSynchronizationBarrier(&gBarrier, (LONG)dwThreads, -1))
{
printf("%s: InitializeSynchronizationBarrier failed. GetLastError() = 0x%08x", __func__,
GetLastError());
goto fail;
}
if (!(gStartEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr)))
{
printf("%s: CreateEvent failed with error 0x%08x", __func__, GetLastError());
goto fail;
}
DWORD i = 0;
for (; i < dwThreads; i++)
{
threads[i] = CreateThread(nullptr, 0, test_synch_barrier_thread, &p, 0, nullptr);
if (!threads[i])
{
printf("%s: CreateThread failed for thread #%" PRIu32 " with error 0x%08x\n", __func__,
i, GetLastError());
InterlockedIncrement(&gErrorCount);
break;
}
}
if (i > 0)
{
if (!SetEvent(gStartEvent))
{
printf("%s: SetEvent(gStartEvent) failed with error = 0x%08x)\n", __func__,
GetLastError());
InterlockedIncrement(&gErrorCount);
}
while (i--)
{
if (WAIT_OBJECT_0 != (dwStatus = WaitForSingleObject(threads[i], INFINITE)))
{
printf("%s: WaitForSingleObject(thread[%" PRIu32 "] unexpectedly returned %" PRIu32
" (error = 0x%08x)\n",
__func__, i, dwStatus, GetLastError());
InterlockedIncrement(&gErrorCount);
}
if (!CloseHandle(threads[i]))
{
printf("%s: CloseHandle(thread[%" PRIu32 "]) failed with error = 0x%08x)\n",
__func__, i, GetLastError());
InterlockedIncrement(&gErrorCount);
}
}
}
if (!CloseHandle(gStartEvent))
{
printf("%s: CloseHandle(gStartEvent) failed with error = 0x%08x)\n", __func__,
GetLastError());
InterlockedIncrement(&gErrorCount);
}
if (p.threadCount != (INT64)dwThreads)
InterlockedIncrement(&gErrorCount);
if (p.trueCount != (INT64)expectedTrueCount)
InterlockedIncrement(&gErrorCount);
if (p.falseCount != (INT64)expectedFalseCount)
InterlockedIncrement(&gErrorCount);
printf("%s: error count: %" PRId32 "\n", __func__, gErrorCount);
printf("%s: thread count: %" PRId32 " (expected %" PRIu32 ")\n", __func__, p.threadCount,
dwThreads);
printf("%s: true count: %" PRId32 " (expected %" PRIu32 ")\n", __func__, p.trueCount,
expectedTrueCount);
printf("%s: false count: %" PRId32 " (expected %" PRIu32 ")\n", __func__, p.falseCount,
expectedFalseCount);
rc = TRUE;
fail:
free((void*)threads);
DeleteSynchronizationBarrier(&gBarrier);
if (gErrorCount > 0)
{
printf("%s: Error test failed with %" PRId32 " reported errors\n", __func__, gErrorCount);
return FALSE;
}
return rc;
}
int TestSynchBarrier(int argc, char* argv[])
{
SYSTEM_INFO sysinfo;
DWORD dwMaxThreads = 0;
DWORD dwMinThreads = 0;
DWORD dwNumLoops = 10;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
GetNativeSystemInfo(&sysinfo);
printf("%s: Number of processors: %" PRIu32 "\n", __func__, sysinfo.dwNumberOfProcessors);
dwMinThreads = sysinfo.dwNumberOfProcessors;
dwMaxThreads = sysinfo.dwNumberOfProcessors * 4;
if (dwMaxThreads > 32)
dwMaxThreads = 32;
/* Test invalid parameters */
if (InitializeSynchronizationBarrier(&gBarrier, 0, -1))
{
(void)fprintf(
stderr,
"%s: InitializeSynchronizationBarrier unecpectedly succeeded with lTotalThreads = 0\n",
__func__);
return -1;
}
if (InitializeSynchronizationBarrier(&gBarrier, -1, -1))
{
(void)fprintf(
stderr,
"%s: InitializeSynchronizationBarrier unecpectedly succeeded with lTotalThreads = -1\n",
__func__);
return -1;
}
if (InitializeSynchronizationBarrier(&gBarrier, 1, -2))
{
(void)fprintf(
stderr,
"%s: InitializeSynchronizationBarrier unecpectedly succeeded with lSpinCount = -2\n",
__func__);
return -1;
}
/* Functional tests */
if (!TestSynchBarrierWithFlags(0, dwMaxThreads, dwNumLoops))
{
(void)fprintf(
stderr,
"%s: TestSynchBarrierWithFlags(0) unecpectedly succeeded with lTotalThreads = -1\n",
__func__);
return -1;
}
if (!TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY, dwMinThreads,
dwNumLoops))
{
(void)fprintf(stderr,
"%s: TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY) "
"unecpectedly succeeded with lTotalThreads = -1\n",
__func__);
return -1;
}
if (!TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY, dwMaxThreads,
dwNumLoops))
{
(void)fprintf(stderr,
"%s: TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY) "
"unecpectedly succeeded with lTotalThreads = -1\n",
__func__);
return -1;
}
printf("%s: Test successfully completed\n", __func__);
return 0;
}