From 118afc0b954ba9d5632b7836ad24e454555ed113 Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Tue, 17 Feb 2026 12:05:42 +0100
Subject: [PATCH] [allocations] fix growth of preallocated buffers

* Replace * 2 with * sizeof(WCHAR) for string usages
* Grow streams and other buffers reasonably, e.g. add 128 elements per
  try and check for possible overflows
* Add constant postfix to force them to 64bit
---
 channels/drive/client/drive_file.c            |  2 +-
 channels/remdesk/common/remdesk_common.c      |  2 +-
 channels/remdesk/server/remdesk_main.c        |  4 +-
 channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c     |  4 +-
 channels/tsmf/client/tsmf_media.c             |  2 +-
 .../urbdrc/client/libusb/libusb_udevice.c     |  4 +-
 .../freeRDPCore/src/main/cpp/android_event.c  | 14 +++-
 client/Windows/wf_cliprdr.c                   | 11 ++-
 client/X11/xf_event.c                         |  6 +-
 libfreerdp/core/gcc.c                         |  3 +-
 libfreerdp/core/orders.c                      |  2 +-
 libfreerdp/core/proxy.c                       |  2 +-
 libfreerdp/crypto/base64.c                    |  2 +-
 winpr/libwinpr/clipboard/synthetic_file.c     |  2 +-
 winpr/libwinpr/crt/buffer.c                   |  2 +-
 winpr/libwinpr/environment/environment.c      | 77 ++++++++++---------
 winpr/libwinpr/file/file.c                    |  2 +-
 winpr/libwinpr/ncrypt/ncrypt.c                |  4 +-
 winpr/libwinpr/ncrypt/ncrypt_pkcs11.c         |  7 +-
 .../libwinpr/path/include/PathAllocCombine.h  |  6 +-
 winpr/libwinpr/sspi/NTLM/ntlm_message.c       |  4 +-
 winpr/libwinpr/utils/collections/BufferPool.c | 15 +++-
 .../libwinpr/utils/collections/MessageQueue.c | 19 +++--
 winpr/libwinpr/utils/collections/ObjectPool.c | 15 ++--
 winpr/libwinpr/utils/collections/PubSub.c     | 16 ++--
 winpr/libwinpr/utils/collections/Stack.c      | 10 ++-
 winpr/libwinpr/utils/stream.c                 | 15 ++--
 winpr/tools/makecert/makecert.c               |  5 +-
 28 files changed, 153 insertions(+), 104 deletions(-)

Index: FreeRDP-3.10.3/channels/drive/client/drive_file.c
===================================================================
--- FreeRDP-3.10.3.orig/channels/drive/client/drive_file.c
+++ FreeRDP-3.10.3/channels/drive/client/drive_file.c
@@ -848,7 +848,7 @@ BOOL drive_file_query_directory(DRIVE_FI
 	else if (!FindNextFileW(file->find_handle, &file->find_data))
 		goto out_fail;
 
-	length = _wcslen(file->find_data.cFileName) * 2;
+	length = _wcslen(file->find_data.cFileName) * sizeof(WCHAR);
 
 	switch (FsInformationClass)
 	{
Index: FreeRDP-3.10.3/channels/remdesk/common/remdesk_common.c
===================================================================
--- FreeRDP-3.10.3.orig/channels/remdesk/common/remdesk_common.c
+++ FreeRDP-3.10.3/channels/remdesk/common/remdesk_common.c
@@ -36,7 +36,7 @@ UINT remdesk_write_channel_header(wStrea
 	}
 
 	const size_t ChannelNameLen =
-	    (strnlen(header->ChannelName, sizeof(header->ChannelName)) + 1) * 2;
+	    (strnlen(header->ChannelName, sizeof(header->ChannelName)) + 1) * sizeof(WCHAR);
 	WINPR_ASSERT(ChannelNameLen <= ARRAYSIZE(header->ChannelName));
 
 	Stream_Write_UINT32(s, (UINT32)ChannelNameLen); /* ChannelNameLen (4 bytes) */
Index: FreeRDP-3.10.3/channels/remdesk/server/remdesk_main.c
===================================================================
--- FreeRDP-3.10.3.orig/channels/remdesk/server/remdesk_main.c
+++ FreeRDP-3.10.3/channels/remdesk/server/remdesk_main.c
@@ -185,7 +185,7 @@ static UINT remdesk_recv_ctl_remote_cont
 		return ERROR_INVALID_DATA;
 
 	cchStringW++;
-	cbRaConnectionStringW = cchStringW * 2;
+    cbRaConnectionStringW = cchStringW * sizeof(WCHAR);
 	pdu.raConnectionString =
 	    ConvertWCharNToUtf8Alloc(raConnectionStringW, cbRaConnectionStringW / sizeof(WCHAR), NULL);
 	if (!pdu.raConnectionString)
@@ -228,7 +228,7 @@ static UINT remdesk_recv_ctl_authenticat
 		return ERROR_INVALID_DATA;
 
 	cchStringW++;
-	cbRaConnectionStringW = cchStringW * 2;
+	cbRaConnectionStringW = cchStringW * sizeof(WCHAR);
 	pStringW += cchStringW;
 	expertBlobW = pStringW;
 	cchStringW = 0;
@@ -243,7 +243,7 @@ static UINT remdesk_recv_ctl_authenticat
 		return ERROR_INVALID_DATA;
 
 	cchStringW++;
-	cbExpertBlobW = cchStringW * 2;
+    cbExpertBlobW = cchStringW * sizeof(WCHAR);
 	pdu.raConnectionString =
 	    ConvertWCharNToUtf8Alloc(raConnectionStringW, cbRaConnectionStringW / sizeof(WCHAR), NULL);
 	if (!pdu.raConnectionString)
Index: FreeRDP-3.10.3/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
===================================================================
--- FreeRDP-3.10.3.orig/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+++ FreeRDP-3.10.3/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
@@ -495,12 +495,12 @@ static BOOL tsmf_ffmpeg_decode_audio(ITS
 		if (mdecoder->decoded_size_max - mdecoder->decoded_size < MAX_AUDIO_FRAME_SIZE)
 		{
 			BYTE* tmp_data = NULL;
-			tmp_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max * 2 + 16);
+			tmp_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max * 2ull + 16ull);
 
 			if (!tmp_data)
 				return FALSE;
 
-			mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16;
+			mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2ull + 16ull;
 			mdecoder->decoded_data = tmp_data;
 			dst = (BYTE*)(((uintptr_t)mdecoder->decoded_data + 15) & ~0x0F);
 
Index: FreeRDP-3.10.3/channels/tsmf/client/tsmf_media.c
===================================================================
--- FreeRDP-3.10.3.orig/channels/tsmf/client/tsmf_media.c
+++ FreeRDP-3.10.3/channels/tsmf/client/tsmf_media.c
@@ -387,7 +387,7 @@ static char* guid_to_string(const BYTE*
 TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE* guid)
 {
 	BOOL found = FALSE;
-	char guid_str[GUID_SIZE * 2 + 1] = { 0 };
+	char guid_str[GUID_SIZE * 2ull + 1] = { 0 };
 	TSMF_PRESENTATION* presentation = NULL;
 	ArrayList_Lock(presentation_list);
 	const size_t count = ArrayList_Count(presentation_list);
Index: FreeRDP-3.10.3/channels/urbdrc/client/libusb/libusb_udevice.c
===================================================================
--- FreeRDP-3.10.3.orig/channels/urbdrc/client/libusb/libusb_udevice.c
+++ FreeRDP-3.10.3/channels/urbdrc/client/libusb/libusb_udevice.c
@@ -904,10 +904,10 @@ static UINT32 libusb_udev_control_query_
 				 * So also check the string length returned as server side does
 				 * not honor strings with multi '\0' characters well.
 				 */
-				const size_t rchar = _wcsnlen((WCHAR*)&data[2], sizeof(data) / 2);
+				const size_t rchar = _wcsnlen((WCHAR*)&data[2], sizeof(data) / sizeof(WCHAR));
 				len = MIN((BYTE)ret - 2, slen);
 				len = MIN(len, inSize);
-				len = MIN(len, rchar * 2 + sizeof(WCHAR));
+				len = MIN(len, rchar * sizeof(WCHAR) + sizeof(WCHAR));
 				memcpy(Buffer, &data[2], len);
 
 				/* Just as above, the returned WCHAR string should be '\0'
Index: FreeRDP-3.10.3/client/Android/Studio/freeRDPCore/src/main/cpp/android_event.c
===================================================================
--- FreeRDP-3.10.3.orig/client/Android/Studio/freeRDPCore/src/main/cpp/android_event.c
+++ FreeRDP-3.10.3/client/Android/Studio/freeRDPCore/src/main/cpp/android_event.c
@@ -28,10 +28,16 @@ BOOL android_push_event(freerdp* inst, A
 
 	if (aCtx->event_queue->count >= aCtx->event_queue->size)
 	{
-		int new_size;
-		void* new_events;
-		new_size = aCtx->event_queue->size * 2;
-		new_events = realloc((void*)aCtx->event_queue->events, sizeof(ANDROID_EVENT*) * new_size);
+		size_t new_size = aCtx->event_queue->size;
+		do
+		{
+			if (new_size >= SIZE_MAX - 128ull)
+				return FALSE;
+
+			new_size += 128ull;
+		} while (new_size <= aCtx->event_queue->count);
+		void* new_events =
+		    realloc((void*)aCtx->event_queue->events, sizeof(ANDROID_EVENT*) * new_size);
 
 		if (!new_events)
 			return FALSE;
Index: FreeRDP-3.10.3/client/Windows/wf_cliprdr.c
===================================================================
--- FreeRDP-3.10.3.orig/client/Windows/wf_cliprdr.c
+++ FreeRDP-3.10.3/client/Windows/wf_cliprdr.c
@@ -1122,10 +1122,13 @@ static void map_ensure_capacity(wfClipbo
 
 	if (clipboard->map_size >= clipboard->map_capacity)
 	{
-		size_t new_size;
-		formatMapping* new_map;
-		new_size = clipboard->map_capacity * 2;
-		new_map =
+		size_t new_size = clipboard->map_capacity;
+		do
+		{
+			WINPR_ASSERT(new_size <= SIZE_MAX - 128ull);
+			new_size += 128ull;
+		} while (new_size <= clipboard->map_size);
+		formatMapping* new_map =
 		    (formatMapping*)realloc(clipboard->format_mappings, sizeof(formatMapping) * new_size);
 
 		if (!new_map)
Index: FreeRDP-3.10.3/client/X11/xf_event.c
===================================================================
--- FreeRDP-3.10.3.orig/client/X11/xf_event.c
+++ FreeRDP-3.10.3/client/X11/xf_event.c
@@ -858,10 +858,8 @@ static BOOL xf_event_ConfigureNotify(xfC
 
 		if (freerdp_settings_get_bool(settings, FreeRDP_DynamicResolutionUpdate))
 		{
-			int alignedWidth = 0;
-			int alignedHeight = 0;
-			alignedWidth = (xfc->window->width / 2) * 2;
-			alignedHeight = (xfc->window->height / 2) * 2;
+			const int alignedWidth = (xfc->window->width / 2) * 2;
+			const int alignedHeight = (xfc->window->height / 2) * 2;
 			/* ask the server to resize using the display channel */
 			xf_disp_handle_configureNotify(xfc, alignedWidth, alignedHeight);
 		}
Index: FreeRDP-3.10.3/libfreerdp/core/gcc.c
===================================================================
--- FreeRDP-3.10.3.orig/libfreerdp/core/gcc.c
+++ FreeRDP-3.10.3/libfreerdp/core/gcc.c
@@ -1958,7 +1958,8 @@ BOOL gcc_write_server_network_data(wStre
 {
 	WINPR_ASSERT(s);
 	WINPR_ASSERT(mcs);
-	const size_t payloadLen = 8 + mcs->channelCount * 2 + (mcs->channelCount % 2 == 1 ? 2 : 0);
+	const size_t payloadLen =
+	    8ull + mcs->channelCount * 2ull + (mcs->channelCount % 2 == 1 ? 2ull : 0ull);
 
 	if (!gcc_write_user_data_header(s, SC_NET, payloadLen))
 		return FALSE;
Index: FreeRDP-3.10.3/libfreerdp/core/orders.c
===================================================================
--- FreeRDP-3.10.3.orig/libfreerdp/core/orders.c
+++ FreeRDP-3.10.3/libfreerdp/core/orders.c
@@ -3279,7 +3279,7 @@ size_t update_approximate_create_offscre
 	deleteList = &(create_offscreen_bitmap->deleteList);
 	WINPR_ASSERT(deleteList);
 
-	return 32 + deleteList->cIndices * 2;
+	return 32ull + deleteList->cIndices * 2ull;
 }
 
 BOOL update_write_create_offscreen_bitmap_order(
Index: FreeRDP-3.10.3/libfreerdp/core/proxy.c
===================================================================
--- FreeRDP-3.10.3.orig/libfreerdp/core/proxy.c
+++ FreeRDP-3.10.3/libfreerdp/core/proxy.c
@@ -553,7 +553,7 @@ static BOOL http_proxy_connect(rdpContex
 
 	hostLen = strlen(hostname);
 	portLen = strnlen(port_str, sizeof(port_str));
-	reserveSize = strlen(connect) + (hostLen + 1 + portLen) * 2 + strlen(httpheader);
+	reserveSize = strlen(connect) + (hostLen + 1ull + portLen) * 2ull + strlen(httpheader);
 	s = Stream_New(NULL, reserveSize);
 	if (!s)
 		goto fail;
Index: FreeRDP-3.10.3/libfreerdp/crypto/base64.c
===================================================================
--- FreeRDP-3.10.3.orig/libfreerdp/crypto/base64.c
+++ FreeRDP-3.10.3/libfreerdp/crypto/base64.c
@@ -313,7 +313,7 @@ static inline char* base64_encode_ex(con
 	if (crLf)
 	{
 		size_t nCrLf = (outLen + lineSize - 1) / lineSize;
-		extra = nCrLf * 2;
+		extra = nCrLf * 2ull;
 	}
 	size_t outCounter = 0;
 
Index: FreeRDP-3.10.3/winpr/libwinpr/clipboard/synthetic_file.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/clipboard/synthetic_file.c
+++ FreeRDP-3.10.3/winpr/libwinpr/clipboard/synthetic_file.c
@@ -763,7 +763,7 @@ static void* convert_filedescriptors_to_
 			alloc += ARRAYSIZE(dsc->cFileName) *
 			         8; /* Overallocate, just take the biggest value the result path can have */
 			            /* # (1 char) -> %23 (3 chars) , the first char is replaced inplace */
-			alloc += count_special_chars(dsc->cFileName) * 2;
+			alloc += count_special_chars(dsc->cFileName) * sizeof(WCHAR);
 			alloc += decoration_len;
 		}
 	}
Index: FreeRDP-3.10.3/winpr/libwinpr/crt/buffer.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/crt/buffer.c
+++ FreeRDP-3.10.3/winpr/libwinpr/crt/buffer.c
@@ -39,7 +39,7 @@ errno_t memmove_s(void* dest, size_t num
 
 errno_t wmemmove_s(WCHAR* dest, size_t numberOfElements, const WCHAR* src, size_t count)
 {
-	if (count * 2 > numberOfElements)
+	if (count * sizeof(WCHAR) > numberOfElements)
 		return -1;
 
 	memmove(dest, src, count * 2);
Index: FreeRDP-3.10.3/winpr/libwinpr/environment/environment.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/environment/environment.c
+++ FreeRDP-3.10.3/winpr/libwinpr/environment/environment.c
@@ -29,6 +29,10 @@
 
 #include <winpr/environment.h>
 
+#include "../log.h"
+
+#define TAG WINPR_TAG("environment")
+
 #ifndef _WIN32
 
 #include <errno.h>
@@ -232,32 +236,35 @@ extern char** environ;
 LPCH GetEnvironmentStringsA(VOID)
 {
 #if !defined(_UWP)
-	char* p = NULL;
 	size_t offset = 0;
-	size_t length = 0;
-	char** envp = NULL;
-	DWORD cchEnvironmentBlock = 0;
-	LPCH lpszEnvironmentBlock = NULL;
+	char** envp = environ;
+	const size_t blocksize = 128;
+	size_t cchEnvironmentBlock = blocksize;
+	LPCH lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock, sizeof(CHAR));
 
-	offset = 0;
-	envp = environ;
-
-	cchEnvironmentBlock = 128;
-	lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock, sizeof(CHAR));
 	if (!lpszEnvironmentBlock)
 		return NULL;
 
 	while (*envp)
 	{
-		length = strlen(*envp);
-
-		while ((offset + length + 8) > cchEnvironmentBlock)
+		const size_t length = strlen(*envp);
+		const size_t required = offset + length + 8ull;
+		if (required > UINT32_MAX)
 		{
-			DWORD new_size = 0;
-			LPCH new_blk = NULL;
+			WLog_ERR(TAG, "Environment block too large: %" PRIuz, required);
 
-			new_size = cchEnvironmentBlock * 2;
-			new_blk = (LPCH)realloc(lpszEnvironmentBlock, new_size * sizeof(CHAR));
+			free(lpszEnvironmentBlock);
+			return NULL;
+		}
+
+		if (required > cchEnvironmentBlock)
+		{
+			size_t new_size = cchEnvironmentBlock;
+			do
+			{
+				new_size += blocksize;
+			} while (new_size <= required);
+			LPCH new_blk = (LPCH)realloc(lpszEnvironmentBlock, new_size * sizeof(CHAR));
 			if (!new_blk)
 			{
 				free(lpszEnvironmentBlock);
@@ -268,12 +275,12 @@ LPCH GetEnvironmentStringsA(VOID)
 			cchEnvironmentBlock = new_size;
 		}
 
-		p = &(lpszEnvironmentBlock[offset]);
+		char* p = &(lpszEnvironmentBlock[offset]);
 
 		CopyMemory(p, *envp, length * sizeof(CHAR));
 		p[length] = '\0';
 
-		offset += (length + 1);
+		offset += (length + 1ull);
 		envp++;
 	}
 
Index: FreeRDP-3.10.3/winpr/libwinpr/file/file.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/file/file.c
+++ FreeRDP-3.10.3/winpr/libwinpr/file/file.c
@@ -1353,7 +1353,7 @@ DWORD GetFullPathNameA(LPCSTR lpFileName
 	free(lpFileNameW);
 	free(lpBufferW);
 
-	return dwStatus * 2;
+	return WINPR_ASSERTING_INT_CAST(DWORD, dwStatus * sizeof(WCHAR));
 }
 
 BOOL GetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector,
Index: FreeRDP-3.10.3/winpr/libwinpr/ncrypt/ncrypt.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/ncrypt/ncrypt.c
+++ FreeRDP-3.10.3/winpr/libwinpr/ncrypt/ncrypt.c
@@ -114,7 +114,7 @@ SECURITY_STATUS NCryptEnumStorageProvide
 
 #ifdef WITH_PKCS11
 	*wProviderCount += 1;
-	stringAllocSize += (_wcslen(MS_SCARD_PROV) + 1) * 2;
+	stringAllocSize += (_wcslen(MS_SCARD_PROV) + 1) * sizeof(WCHAR);
 	stringAllocSize += sizeof(emptyComment);
 #endif
 
@@ -129,7 +129,7 @@ SECURITY_STATUS NCryptEnumStorageProvide
 	strPtr = (LPWSTR)(ret + *wProviderCount);
 
 	ret->pszName = strPtr;
-	copyAmount = (_wcslen(MS_SCARD_PROV) + 1) * 2;
+	copyAmount = (_wcslen(MS_SCARD_PROV) + 1) * sizeof(WCHAR);
 	memcpy(strPtr, MS_SCARD_PROV, copyAmount);
 	strPtr += copyAmount / 2;
 
Index: FreeRDP-3.10.3/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c
+++ FreeRDP-3.10.3/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c
@@ -815,11 +815,12 @@ static SECURITY_STATUS NCryptP11EnumKeys
 		{
 			/* sizeof keyName struct + "\<slotId>\<certId>" + keyName->pszAlgid */
 			DWORD algoSz = 0;
-			size_t KEYNAME_SZ =
-			    (1 + (sizeof(key->slotId) * 2) /*slotId*/ + 1 + (key->idLen * 2) + 1) * 2;
+			size_t KEYNAME_SZ = (1ull + (sizeof(key->slotId) * 2ull) /*slotId*/ + 1ull +
+			                     (key->idLen * 2ull) + 1ull) *
+			                    sizeof(WCHAR);
 
 			convertKeyType(key->keyType, NULL, 0, &algoSz);
-			KEYNAME_SZ += (1ULL + algoSz) * 2ULL;
+			KEYNAME_SZ += (1ULL + algoSz) * sizeof(WCHAR);
 
 			keyName = calloc(1, sizeof(*keyName) + KEYNAME_SZ);
 			if (!keyName)
Index: FreeRDP-3.10.3/winpr/libwinpr/path/include/PathAllocCombine.h
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/path/include/PathAllocCombine.h
+++ FreeRDP-3.10.3/winpr/libwinpr/path/include/PathAllocCombine.h
@@ -78,7 +78,7 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPat
 	{
 		const WCHAR sep[] = CUR_PATH_SEPARATOR_STR;
 		const size_t pszPathOutLength = pszPathInLength + pszMoreLength;
-		const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
+		const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
 		PWSTR pszPathOut = (PWSTR)calloc(sizeOfBuffer, 2);
 
 		if (!pszPathOut)
@@ -130,7 +130,7 @@ HRESULT PATH_ALLOC_COMBINE(PCSTR pszPath
 		if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
 		{
 			const size_t pszPathOutLength = 2 + pszMoreLength;
-			const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
+			const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
 			PSTR pszPathOut = calloc(sizeOfBuffer, 2);
 
 			if (!pszPathOut)
@@ -144,7 +144,7 @@ HRESULT PATH_ALLOC_COMBINE(PCSTR pszPath
 	else
 	{
 		const size_t pszPathOutLength = pszPathInLength + pszMoreLength;
-		const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
+		const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
 		PSTR pszPathOut = calloc(sizeOfBuffer, 2);
 
 		if (!pszPathOut)
Index: FreeRDP-3.10.3/winpr/libwinpr/sspi/NTLM/ntlm_message.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/sspi/NTLM/ntlm_message.c
+++ FreeRDP-3.10.3/winpr/libwinpr/sspi/NTLM/ntlm_message.c
@@ -1278,11 +1278,11 @@ SECURITY_STATUS ntlm_write_AuthenticateM
 	if (credentials->identity.DomainLength > 0)
 	{
 		message->NegotiateFlags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
-		message->DomainName.Len = (UINT16)credentials->identity.DomainLength * 2;
+		message->DomainName.Len = (UINT16)credentials->identity.DomainLength * sizeof(WCHAR);
 		message->DomainName.Buffer = (BYTE*)credentials->identity.Domain;
 	}
 
-	message->UserName.Len = (UINT16)credentials->identity.UserLength * 2;
+	message->UserName.Len = (UINT16)credentials->identity.UserLength * sizeof(WCHAR);
 	message->UserName.Buffer = (BYTE*)credentials->identity.User;
 	message->LmChallengeResponse.Len = (UINT16)context->LmChallengeResponse.cbBuffer;
 	message->LmChallengeResponse.Buffer = (BYTE*)context->LmChallengeResponse.pvBuffer;
Index: FreeRDP-3.10.3/winpr/libwinpr/utils/collections/BufferPool.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/utils/collections/BufferPool.c
+++ FreeRDP-3.10.3/winpr/libwinpr/utils/collections/BufferPool.c
@@ -116,9 +116,20 @@ static BOOL BufferPool_ShiftUsed(wBuffer
 {
 	if (count > 0)
 	{
-		if (pool->uSize + count > pool->uCapacity)
+		const SSIZE_T required = pool->uSize + count;
+		// check for overflow
+		if ((required < count) || (required < pool->uSize))
+			return FALSE;
+
+		if (required > pool->uCapacity)
 		{
-			SSIZE_T newUCapacity = pool->uCapacity * 2;
+			SSIZE_T newUCapacity = pool->uCapacity;
+			do
+			{
+				if (newUCapacity > SIZE_MAX - 128ull)
+					return FALSE;
+				newUCapacity += 128ull;
+			} while (newUCapacity <= required);
 			wBufferPoolItem* newUArray = NULL;
 			if (pool->alignment > 0)
 				newUArray = (wBufferPoolItem*)winpr_aligned_realloc(
Index: FreeRDP-3.10.3/winpr/libwinpr/utils/collections/MessageQueue.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/utils/collections/MessageQueue.c
+++ FreeRDP-3.10.3/winpr/libwinpr/utils/collections/MessageQueue.c
@@ -96,16 +96,25 @@ static BOOL MessageQueue_EnsureCapacity(
 {
 	WINPR_ASSERT(queue);
 
-	if (queue->size + count >= queue->capacity)
+	const size_t required = queue->size + count;
+	// check for overflow
+	if ((required < queue->size) || (required < count))
+		return FALSE;
+
+	if (required >= queue->capacity)
 	{
-		wMessage* new_arr = NULL;
 		size_t old_capacity = queue->capacity;
-		size_t new_capacity = queue->capacity * 2;
+		size_t new_capacity = queue->capacity;
 
-		if (new_capacity < queue->size + count)
+		if (new_capacity < required)
+		{
 			new_capacity = queue->size + count;
+			// check for overflow
+			if (new_capacity < old_capacity)
+				return FALSE;
+		}
 
-		new_arr = (wMessage*)realloc(queue->array, sizeof(wMessage) * new_capacity);
+		wMessage* new_arr = (wMessage*)realloc(queue->array, sizeof(wMessage) * new_capacity);
 		if (!new_arr)
 			return FALSE;
 		queue->array = new_arr;
Index: FreeRDP-3.10.3/winpr/libwinpr/utils/collections/ObjectPool.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/utils/collections/ObjectPool.c
+++ FreeRDP-3.10.3/winpr/libwinpr/utils/collections/ObjectPool.c
@@ -92,13 +92,18 @@ void ObjectPool_Return(wObjectPool* pool
 {
 	ObjectPool_Lock(pool);
 
-	if ((pool->size + 1) >= pool->capacity)
+	WINPR_ASSERT(pool->size < SIZE_MAX);
+	const size_t required = pool->size + 1ull;
+	if (required >= pool->capacity)
 	{
-		size_t new_cap = 0;
-		void** new_arr = NULL;
+		size_t new_cap = pool->capacity;
+		do
+		{
+			WINPR_ASSERT(new_cap <= SIZE_MAX - 128ull);
+			new_cap += 128ull;
+		} while (new_cap <= required);
 
-		new_cap = pool->capacity * 2;
-		new_arr = (void**)realloc((void*)pool->array, sizeof(void*) * new_cap);
+		void** new_arr = (void**)realloc((void*)pool->array, sizeof(void*) * new_cap);
 		if (!new_arr)
 			goto out;
 
Index: FreeRDP-3.10.3/winpr/libwinpr/utils/collections/PubSub.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/utils/collections/PubSub.c
+++ FreeRDP-3.10.3/winpr/libwinpr/utils/collections/PubSub.c
@@ -94,13 +94,19 @@ void PubSub_AddEventTypes(wPubSub* pubSu
 	if (pubSub->synchronized)
 		PubSub_Lock(pubSub);
 
-	while (pubSub->count + count >= pubSub->size)
+	const size_t required = pubSub->count + count;
+	WINPR_ASSERT((required >= pubSub->count) && (required >= count));
+
+	if (required >= pubSub->size)
 	{
-		size_t new_size = 0;
-		wEventType* new_event = NULL;
+		size_t new_size = pubSub->size;
+		do
+		{
+			WINPR_ASSERT(new_size <= SIZE_MAX - 128ull);
+			new_size += 128ull;
+		} while (new_size <= required);
 
-		new_size = pubSub->size * 2;
-		new_event = (wEventType*)realloc(pubSub->events, new_size * sizeof(wEventType));
+		wEventType* new_event = (wEventType*)realloc(pubSub->events, new_size * sizeof(wEventType));
 		if (!new_event)
 			goto fail;
 		pubSub->size = new_size;
Index: FreeRDP-3.10.3/winpr/libwinpr/utils/collections/Stack.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/utils/collections/Stack.c
+++ FreeRDP-3.10.3/winpr/libwinpr/utils/collections/Stack.c
@@ -141,9 +141,15 @@ void Stack_Push(wStack* stack, void* obj
 	if (stack->synchronized)
 		EnterCriticalSection(&stack->lock);
 
-	if ((stack->size + 1) >= stack->capacity)
+	WINPR_ASSERT(stack->size < SIZE_MAX);
+	if ((stack->size + 1ull) >= stack->capacity)
 	{
-		const size_t new_cap = stack->capacity * 2;
+		size_t new_cap = stack->capacity;
+		do
+		{
+			WINPR_ASSERT(new_cap <= SIZE_MAX - 128ull);
+			new_cap += 128ull;
+		} while (new_cap <= stack->size + 1ull);
 		void** new_arr = (void**)realloc((void*)stack->array, sizeof(void*) * new_cap);
 
 		if (!new_arr)
Index: FreeRDP-3.10.3/winpr/libwinpr/utils/stream.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/libwinpr/utils/stream.c
+++ FreeRDP-3.10.3/winpr/libwinpr/utils/stream.c
@@ -46,20 +46,19 @@ BOOL Stream_EnsureCapacity(wStream* s, s
 	WINPR_ASSERT(s);
 	if (s->capacity < size)
 	{
-		size_t position = 0;
-		size_t old_capacity = 0;
-		size_t new_capacity = 0;
 		BYTE* new_buf = NULL;
 
-		old_capacity = s->capacity;
-		new_capacity = old_capacity;
+		size_t old_capacity = s->capacity;
+		size_t new_capacity = old_capacity;
 
 		do
 		{
-			new_capacity *= 2;
-		} while (new_capacity < size);
+			if (new_capacity > SIZE_MAX - 128ull)
+				return FALSE;
+			new_capacity += 128ull;
+		} while (new_capacity <= size);
 
-		position = Stream_GetPosition(s);
+		const size_t position = Stream_GetPosition(s);
 
 		if (!s->isOwner)
 		{
Index: FreeRDP-3.10.3/winpr/tools/makecert/makecert.c
===================================================================
--- FreeRDP-3.10.3.orig/winpr/tools/makecert/makecert.c
+++ FreeRDP-3.10.3/winpr/tools/makecert/makecert.c
@@ -78,12 +78,9 @@ static char* makecert_read_str(BIO* bio,
 
 	while (offset >= length)
 	{
-		size_t new_len = 0;
 		size_t readBytes = 0;
 		char* new_str = NULL;
-		new_len = length * 2;
-		if (new_len == 0)
-			new_len = 2048;
+		size_t new_len = length + 2048ull;
 
 		if (new_len > INT_MAX)
 		{
