From e2d98d03b204d58afd538f0792396aa7a9387f21 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Sat, 28 Feb 2026 10:56:23 +0100 Subject: [PATCH 1/2] [winpr,crypto] fix CryptProtectMemory regression in bb4b7a86934060a6a0db55f11789bc466f8f20c1 introduced checks did not free resources in all branches. --- winpr/libwinpr/crypto/crypto.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/winpr/libwinpr/crypto/crypto.c b/winpr/libwinpr/crypto/crypto.c index c340d72f2..a35d1aafb 100644 --- a/winpr/libwinpr/crypto/crypto.c +++ b/winpr/libwinpr/crypto/crypto.c @@ -155,6 +155,9 @@ BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags) if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS) return FALSE; + if (winpr_RAND(randomKey, sizeof(randomKey)) < 0) + return FALSE; + if (!g_ProtectedMemoryBlocks) { g_ProtectedMemoryBlocks = ListDictionary_New(TRUE); @@ -173,13 +176,11 @@ BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags) pMemBlock->dwFlags = dwFlags; if (winpr_RAND(pMemBlock->salt, 8) < 0) - return FALSE; - if (winpr_RAND(randomKey, sizeof(randomKey)) < 0) - return FALSE; + goto out; if (winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, pMemBlock->salt, randomKey, sizeof(randomKey), 4, pMemBlock->key, pMemBlock->iv) <= 0) - return FALSE; + goto out; SecureZeroMemory(randomKey, sizeof(randomKey)); From b6a0c94008ece9190219ebb05496f3194c774742 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Sat, 28 Feb 2026 10:57:50 +0100 Subject: [PATCH 2/2] [winpr,utils] simplify ObjectPool Clean up and centralize resource allocation and free for ObjectPool --- winpr/libwinpr/utils/collections/ObjectPool.c | 92 +++++++++---------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/winpr/libwinpr/utils/collections/ObjectPool.c b/winpr/libwinpr/utils/collections/ObjectPool.c index 2444f1794..82f522871 100644 --- a/winpr/libwinpr/utils/collections/ObjectPool.c +++ b/winpr/libwinpr/utils/collections/ObjectPool.c @@ -84,6 +84,26 @@ void* ObjectPool_Take(wObjectPool* pool) return obj; } +static BOOL ObjectPool_EnsureCapacity(wObjectPool* pool, size_t add) +{ + WINPR_ASSERT(pool->size < SIZE_MAX - add); + + const size_t blocksize = 128ull; + const size_t required = pool->size + add; + if (required >= pool->capacity) + { + const size_t new_cap = required + blocksize - required % blocksize; + + void** new_arr = (void**)realloc((void*)pool->array, sizeof(void*) * new_cap); + if (!new_arr) + return FALSE; + + pool->array = new_arr; + pool->capacity = new_cap; + } + return TRUE; +} + /** * Returns an object to the pool. */ @@ -92,24 +112,8 @@ void ObjectPool_Return(wObjectPool* pool, void* obj) { ObjectPool_Lock(pool); - WINPR_ASSERT(pool->size < SIZE_MAX); - const size_t required = pool->size + 1ull; - if (required >= pool->capacity) - { - size_t new_cap = pool->capacity; - do - { - WINPR_ASSERT(new_cap <= SIZE_MAX - 128ull); - new_cap += 128ull; - } while (new_cap <= required); - - void** new_arr = (void**)realloc((void*)pool->array, sizeof(void*) * new_cap); - if (!new_arr) - goto out; - - pool->array = new_arr; - pool->capacity = new_cap; - } + if (!ObjectPool_EnsureCapacity(pool, 1)) + goto out; pool->array[(pool->size)++] = obj; @@ -151,46 +155,40 @@ void ObjectPool_Clear(wObjectPool* pool) wObjectPool* ObjectPool_New(BOOL synchronized) { - wObjectPool* pool = nullptr; + wObjectPool* pool = (wObjectPool*)calloc(1, sizeof(wObjectPool)); - pool = (wObjectPool*)calloc(1, sizeof(wObjectPool)); + if (!pool) + goto fail; - if (pool) + pool->synchronized = synchronized; + + if (pool->synchronized) { - pool->capacity = 32; - pool->size = 0; - pool->array = (void**)calloc(pool->capacity, sizeof(void*)); - if (!pool->array) - { - free(pool); - return nullptr; - } - pool->synchronized = synchronized; - - if (pool->synchronized) - { - if (!InitializeCriticalSectionAndSpinCount(&pool->lock, 4000)) - { - free(pool); - return nullptr; - } - } + if (!InitializeCriticalSectionAndSpinCount(&pool->lock, 4000)) + goto fail; } + if (!ObjectPool_EnsureCapacity(pool, 32)) + goto fail; + return pool; + +fail: + ObjectPool_Free(pool); + return nullptr; } void ObjectPool_Free(wObjectPool* pool) { - if (pool) - { - ObjectPool_Clear(pool); + if (!pool) + return; - if (pool->synchronized) - DeleteCriticalSection(&pool->lock); + ObjectPool_Clear(pool); - free((void*)pool->array); + if (pool->synchronized) + DeleteCriticalSection(&pool->lock); - free(pool); - } + free((void*)pool->array); + + free(pool); }