import Oracle_OSS freerdp-3.10.3-5.el10_1.5

This commit is contained in:
AlmaLinux RelEng Bot 2026-04-07 20:33:51 -04:00
parent b283e4ffa5
commit 33ebd2c72c
24 changed files with 1348 additions and 1 deletions

View File

@ -0,0 +1,117 @@
From afa6851dc80835d3101e40fcef51b6c5c0f43ea5 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Wed, 28 Jan 2026 09:31:06 +0100
Subject: [PATCH] [channel,rdpsnd] only clean up thread before free
rdpsnd channel usually has multiple instances (static, dynamic, ...) so
ensure only to terminate the handler thread when the channel is actually
closed for good.
---
channels/rdpsnd/client/rdpsnd_main.c | 43 ++++++++++++++++------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c
index 61a29ec40..5a1edaea6 100644
--- a/channels/rdpsnd/client/rdpsnd_main.c
+++ b/channels/rdpsnd/client/rdpsnd_main.c
@@ -117,6 +117,8 @@ struct rdpsnd_plugin
BOOL async;
};
+static DWORD WINAPI play_thread(LPVOID arg);
+
static const char* rdpsnd_is_dyn_str(BOOL dynamic)
{
if (dynamic)
@@ -1300,7 +1302,6 @@ static void cleanup_internals(rdpsndPlugin* rdpsnd)
if (!rdpsnd)
return;
- rdpsnd_terminate_thread(rdpsnd);
if (rdpsnd->pool)
StreamPool_Return(rdpsnd->pool, rdpsnd->data_in);
@@ -1376,6 +1377,7 @@ static void free_internals(rdpsndPlugin* rdpsnd)
if (rdpsnd->references > 0)
return;
+ rdpsnd_terminate_thread(rdpsnd);
freerdp_dsp_context_free(rdpsnd->dsp_context);
StreamPool_Free(rdpsnd->pool);
rdpsnd->pool = NULL;
@@ -1399,6 +1401,27 @@ static BOOL allocate_internals(rdpsndPlugin* rdpsnd)
if (!rdpsnd->dsp_context)
return FALSE;
}
+
+ if (rdpsnd->async)
+ {
+ if (!rdpsnd->queue)
+ {
+ wObject obj = { 0 };
+
+ obj.fnObjectFree = queue_free;
+ rdpsnd->queue = MessageQueue_New(&obj);
+ if (!rdpsnd->queue)
+ return CHANNEL_RC_NO_MEMORY;
+ }
+
+ if (!rdpsnd->thread)
+ {
+ rdpsnd->thread = CreateThread(NULL, 0, play_thread, rdpsnd, 0, NULL);
+ if (!rdpsnd->thread)
+ return CHANNEL_RC_INITIALIZATION_ERROR;
+ }
+ }
+
rdpsnd->references++;
return TRUE;
@@ -1454,20 +1477,6 @@ static UINT rdpsnd_virtual_channel_event_initialized(rdpsndPlugin* rdpsnd)
if (!rdpsnd)
return ERROR_INVALID_PARAMETER;
- if (rdpsnd->async)
- {
- wObject obj = { 0 };
-
- obj.fnObjectFree = queue_free;
- rdpsnd->queue = MessageQueue_New(&obj);
- if (!rdpsnd->queue)
- return CHANNEL_RC_NO_MEMORY;
-
- rdpsnd->thread = CreateThread(NULL, 0, play_thread, rdpsnd, 0, NULL);
- if (!rdpsnd->thread)
- return CHANNEL_RC_INITIALIZATION_ERROR;
- }
-
if (!allocate_internals(rdpsnd))
return CHANNEL_RC_NO_MEMORY;
@@ -1478,8 +1487,6 @@ void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd)
{
if (rdpsnd)
{
- rdpsnd_terminate_thread(rdpsnd);
-
free_internals(rdpsnd);
audio_formats_free(rdpsnd->fixed_format, 1);
free(rdpsnd->subsystem);
@@ -1701,13 +1708,13 @@ static UINT rdpsnd_on_close(IWTSVirtualChannelCallback* pChannelCallback)
cleanup_internals(rdpsnd);
+ free_internals(rdpsnd);
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->Free, rdpsnd->device);
rdpsnd->device = NULL;
}
- free_internals(rdpsnd);
free(pChannelCallback);
return CHANNEL_RC_OK;
}
--
2.53.0

View File

@ -0,0 +1,112 @@
From d9ca272dce7a776ab475e9b1a8e8c3d2968c8486 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 12:08:48 +0100
Subject: [PATCH] [channels,ainput] lock context when updating listener
---
channels/ainput/client/ainput_main.c | 36 ++++++++++++++++++++--------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/channels/ainput/client/ainput_main.c b/channels/ainput/client/ainput_main.c
index c291bd727..554575360 100644
--- a/channels/ainput/client/ainput_main.c
+++ b/channels/ainput/client/ainput_main.c
@@ -45,6 +45,7 @@ struct AINPUT_PLUGIN_
AInputClientContext* context;
UINT32 MajorVersion;
UINT32 MinorVersion;
+ CRITICAL_SECTION lock;
};
/**
@@ -85,18 +86,15 @@ static UINT ainput_on_data_received(IWTSVirtualChannelCallback* pChannelCallback
static UINT ainput_send_input_event(AInputClientContext* context, UINT64 flags, INT32 x, INT32 y)
{
- AINPUT_PLUGIN* ainput = NULL;
- GENERIC_CHANNEL_CALLBACK* callback = NULL;
BYTE buffer[32] = { 0 };
- UINT64 time = 0;
wStream sbuffer = { 0 };
wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
WINPR_ASSERT(s);
WINPR_ASSERT(context);
- time = GetTickCount64();
- ainput = (AINPUT_PLUGIN*)context->handle;
+ const UINT64 time = GetTickCount64();
+ AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)context->handle;
WINPR_ASSERT(ainput);
if (ainput->MajorVersion != AINPUT_VERSION_MAJOR)
@@ -105,8 +103,6 @@ static UINT ainput_send_input_event(AInputClientContext* context, UINT64 flags,
ainput->MajorVersion, ainput->MinorVersion);
return CHANNEL_RC_UNSUPPORTED_VERSION;
}
- callback = ainput->base.listener_callback->channel_callback;
- WINPR_ASSERT(callback);
{
char ebuffer[128] = { 0 };
@@ -125,10 +121,15 @@ static UINT ainput_send_input_event(AInputClientContext* context, UINT64 flags,
Stream_SealLength(s);
/* ainput back what we have received. AINPUT does not have any message IDs. */
+ EnterCriticalSection(&ainput->lock);
+ GENERIC_CHANNEL_CALLBACK* callback = ainput->base.listener_callback->channel_callback;
+ WINPR_ASSERT(callback);
WINPR_ASSERT(callback->channel);
WINPR_ASSERT(callback->channel->Write);
- return callback->channel->Write(callback->channel, (ULONG)Stream_Length(s), Stream_Buffer(s),
- NULL);
+ const UINT rc = callback->channel->Write(callback->channel, (ULONG)Stream_Length(s),
+ Stream_Buffer(s), NULL);
+ LeaveCriticalSection(&ainput->lock);
+ return rc;
}
/**
@@ -140,8 +141,16 @@ static UINT ainput_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
GENERIC_CHANNEL_CALLBACK* callback = (GENERIC_CHANNEL_CALLBACK*)pChannelCallback;
- free(callback);
+ if (callback)
+ {
+ AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)callback->plugin;
+ WINPR_ASSERT(ainput);
+ /* Lock here to ensure that no ainput_send_input_event is in progress. */
+ EnterCriticalSection(&ainput->lock);
+ free(callback);
+ LeaveCriticalSection(&ainput->lock);
+ }
return CHANNEL_RC_OK;
}
@@ -156,14 +165,21 @@ static UINT init_plugin_cb(GENERIC_DYNVC_PLUGIN* base, WINPR_ATTR_UNUSED rdpCont
context->handle = (void*)base;
context->AInputSendInputEvent = ainput_send_input_event;
+ InitializeCriticalSection(&ainput->lock);
+
+ EnterCriticalSection(&ainput->lock);
ainput->context = context;
ainput->base.iface.pInterface = context;
+ LeaveCriticalSection(&ainput->lock);
return CHANNEL_RC_OK;
}
static void terminate_plugin_cb(GENERIC_DYNVC_PLUGIN* base)
{
AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)base;
+ WINPR_ASSERT(ainput);
+
+ DeleteCriticalSection(&ainput->lock);
free(ainput->context);
}
--
2.53.0

View File

@ -0,0 +1,29 @@
From 1c5c74223179d425a1ce6dbbb6a3dd2a958b7aee Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:14:08 +0100
Subject: [PATCH] [channels,audin] fix audin_server_recv_formats cleanup
---
channels/audin/server/audin.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c
index 5046a7d6f..17077efa6 100644
--- a/channels/audin/server/audin.c
+++ b/channels/audin/server/audin.c
@@ -146,11 +146,7 @@ static UINT audin_server_recv_formats(audin_server_context* context, wStream* s,
AUDIO_FORMAT* format = &pdu.SoundFormats[i];
if (!audio_format_read(s, format))
- {
- WLog_Print(audin->log, WLOG_ERROR, "Failed to read audio format");
- audio_formats_free(pdu.SoundFormats, i + i);
- return ERROR_INVALID_DATA;
- }
+ goto fail;
audio_format_print(audin->log, WLOG_DEBUG, format);
}
--
2.53.0

View File

@ -0,0 +1,27 @@
From cd1ffa112cfbe1b40a9fd57e299a8ea12e23df0d Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Sat, 10 Jan 2026 08:36:38 +0100
Subject: [PATCH] [channels,audin] free up old audio formats
---
channels/audin/client/audin_main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c
index bcaf1a646..b4c8ba580 100644
--- a/channels/audin/client/audin_main.c
+++ b/channels/audin/client/audin_main.c
@@ -206,6 +206,10 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
}
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */
+
+ audio_formats_free(callback->formats, callback->formats_count);
+ callback->formats_count = 0;
+
callback->formats = audio_formats_new(NumFormats);
if (!callback->formats)
--
2.53.0

View File

@ -0,0 +1,33 @@
From 026b81ae5831ac1598d8f7371e0d0996fac7db00 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:20:23 +0100
Subject: [PATCH] [channels,audin] reset audin->format
Whenever the underlying structure changes reset the pointer to NULL
---
channels/audin/client/audin_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c
index c57c65a62..76d87bb9c 100644
--- a/channels/audin/client/audin_main.c
+++ b/channels/audin/client/audin_main.c
@@ -207,6 +207,7 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */
+ audin->format = NULL;
audio_formats_free(callback->formats, callback->formats_count);
callback->formats_count = 0;
@@ -284,6 +285,7 @@ out:
if (error != CHANNEL_RC_OK)
{
+ audin->format = NULL;
audio_formats_free(callback->formats, NumFormats);
callback->formats = NULL;
}
--
2.53.0

View File

@ -0,0 +1,34 @@
From 668352a2e241ba017679c11a22ecbe29d0b17401 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 17 Mar 2026 09:34:08 +0100
Subject: [PATCH] [channels,audin] set error when audio_format_read fails
Currently, `goto fail` is called when `audio_format_read` fails, but
`error` is not changed, so `CHANNEL_RC_OK` is returned. Before the
1c5c7422 commit, `ERROR_INVALID_DATA` was returned. Let's again set
that error code and also restore the debug print.
Made-with: Cursor
---
channels/audin/server/audin.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c
index ae36df6bf..1d3ddd411 100644
--- a/channels/audin/server/audin.c
+++ b/channels/audin/server/audin.c
@@ -146,7 +146,11 @@ static UINT audin_server_recv_formats(audin_server_context* context, wStream* s,
AUDIO_FORMAT* format = &pdu.SoundFormats[i];
if (!audio_format_read(s, format))
+ {
+ WLog_Print(audin->log, WLOG_ERROR, "Failed to read audio format");
+ error = ERROR_INVALID_DATA;
goto fail;
+ }
audio_format_print(audin->log, WLOG_DEBUG, format);
}
--
2.53.0

View File

@ -0,0 +1,33 @@
From 54ab7e13650f3ef9d912e9d0e336b9d7f22537ca Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Thu, 12 Mar 2026 10:20:59 +0100
Subject: [PATCH] [channels,drdynvc] check pointer before reset
Backport of commit cb7f295bc750de86480d60a3b58cebc56a57a1c4.
Made-with: Cursor
---
channels/drdynvc/client/drdynvc_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c
index e1c121f55..06ee325e5 100644
--- a/channels/drdynvc/client/drdynvc_main.c
+++ b/channels/drdynvc/client/drdynvc_main.c
@@ -486,11 +486,12 @@ static UINT dvcman_channel_close(DVCMAN_CHANNEL* channel, BOOL perRequest, BOOL
channel->state = DVC_CHANNEL_CLOSED;
+ check_open_close_receive(channel);
+
IWTSVirtualChannelCallback* cb = channel->channel_callback;
channel->channel_callback = NULL;
if (cb)
{
- check_open_close_receive(channel);
IFCALL(cb->OnClose, cb);
}
--
2.53.0

View File

@ -0,0 +1,35 @@
From 429260893d7f67011d916394974ec0294ff65a90 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Wed, 11 Mar 2026 09:16:34 +0100
Subject: [PATCH] [channels,drdynvc] reset channel_callback before close
Backport of commit e02e052f6692550e539d10f99de9c35a23492db2.
Made-with: Cursor
---
channels/drdynvc/client/drdynvc_main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c
index 62ff674e5..e1c121f55 100644
--- a/channels/drdynvc/client/drdynvc_main.c
+++ b/channels/drdynvc/client/drdynvc_main.c
@@ -487,14 +487,13 @@ static UINT dvcman_channel_close(DVCMAN_CHANNEL* channel, BOOL perRequest, BOOL
channel->state = DVC_CHANNEL_CLOSED;
IWTSVirtualChannelCallback* cb = channel->channel_callback;
+ channel->channel_callback = NULL;
if (cb)
{
check_open_close_receive(channel);
IFCALL(cb->OnClose, cb);
}
- channel->channel_callback = NULL;
-
if (channel->dvcman && channel->dvcman->drdynvc)
{
if (context)
--
2.53.0

View File

@ -0,0 +1,26 @@
From 3da319570c8a6be0a79b3306f1ed354c4a943259 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 12 Jan 2026 03:44:06 +0100
Subject: [PATCH] [channels,drive] fix constant type
ensure constant is of 64bit integer type
---
channels/drive/client/drive_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c
index 1dce5c348..13188fbc6 100644
--- a/channels/drive/client/drive_main.c
+++ b/channels/drive/client/drive_main.c
@@ -302,7 +302,7 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp)
Length = 0;
}
- if (!Stream_EnsureRemainingCapacity(irp->output, Length + 4))
+ if (!Stream_EnsureRemainingCapacity(irp->output, 4ull + Length))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return ERROR_INTERNAL_ERROR;
--
2.53.0

View File

@ -0,0 +1,65 @@
From 622bb7b4402491ca003f47472d0e478132673696 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:48:14 +0100
Subject: [PATCH] [channels,rdpsnd] terminate thread before free
Ensure that the optional rdpsnd thread is terminated and the message
queue freed up before releasing the channel context memory
---
channels/rdpsnd/client/rdpsnd_main.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c
index 49c763a87..61a29ec40 100644
--- a/channels/rdpsnd/client/rdpsnd_main.c
+++ b/channels/rdpsnd/client/rdpsnd_main.c
@@ -1278,11 +1278,29 @@ fail:
return CHANNEL_RC_NO_MEMORY;
}
+static void rdpsnd_terminate_thread(rdpsndPlugin* rdpsnd)
+{
+ WINPR_ASSERT(rdpsnd);
+ if (rdpsnd->queue)
+ MessageQueue_PostQuit(rdpsnd->queue, 0);
+
+ if (rdpsnd->thread)
+ {
+ (void)WaitForSingleObject(rdpsnd->thread, INFINITE);
+ (void)CloseHandle(rdpsnd->thread);
+ }
+
+ MessageQueue_Free(rdpsnd->queue);
+ rdpsnd->thread = NULL;
+ rdpsnd->queue = NULL;
+}
+
static void cleanup_internals(rdpsndPlugin* rdpsnd)
{
if (!rdpsnd)
return;
+ rdpsnd_terminate_thread(rdpsnd);
if (rdpsnd->pool)
StreamPool_Return(rdpsnd->pool, rdpsnd->data_in);
@@ -1460,15 +1478,7 @@ void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd)
{
if (rdpsnd)
{
- if (rdpsnd->queue)
- MessageQueue_PostQuit(rdpsnd->queue, 0);
-
- if (rdpsnd->thread)
- {
- (void)WaitForSingleObject(rdpsnd->thread, INFINITE);
- (void)CloseHandle(rdpsnd->thread);
- }
- MessageQueue_Free(rdpsnd->queue);
+ rdpsnd_terminate_thread(rdpsnd);
free_internals(rdpsnd);
audio_formats_free(rdpsnd->fixed_format, 1);
--
2.53.0

View File

@ -0,0 +1,47 @@
From 675c20f08f32ca5ec06297108bdf30147d6e2cd9 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Tue, 13 Jan 2026 09:39:33 +0100
Subject: [PATCH] [channels,serial] explicitly lock serial->IrpThreads
---
channels/serial/client/serial_main.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c
index 7ec744afa..59ef0cb9b 100644
--- a/channels/serial/client/serial_main.c
+++ b/channels/serial/client/serial_main.c
@@ -626,7 +626,10 @@ static void create_irp_thread(SERIAL_DEVICE* serial, IRP* irp)
* observed with FreeRDP).
*/
key = irp->CompletionId + 1ull;
+
+ ListDictionary_Lock(serial->IrpThreads);
previousIrpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)key);
+ ListDictionary_Unlock(serial->IrpThreads);
if (previousIrpThread)
{
@@ -742,7 +745,10 @@ static DWORD WINAPI serial_thread_func(LPVOID arg)
create_irp_thread(serial, irp);
}
+ ListDictionary_Lock(serial->IrpThreads);
ListDictionary_Clear(serial->IrpThreads);
+ ListDictionary_Unlock(serial->IrpThreads);
+
if (error && serial->rdpcontext)
setChannelError(serial->rdpcontext, error, "serial_thread_func reported an error");
@@ -971,7 +977,7 @@ FREERDP_ENTRY_POINT(
}
/* IrpThreads content only modified by create_irp_thread() */
- serial->IrpThreads = ListDictionary_New(TRUE);
+ serial->IrpThreads = ListDictionary_New(FALSE);
if (!serial->IrpThreads)
{
--
2.53.0

View File

@ -0,0 +1,87 @@
From b35aa3614d32bff3fc1272cd7c4617f711fca1a4 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 12 Jan 2026 09:02:50 +0100
Subject: [PATCH] [channels,serial] lock list dictionary
prevent sync problems for list dictionary
---
channels/serial/client/serial_main.c | 35 ++++++++++++++++------------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c
index 308afe217..7ec744afa 100644
--- a/channels/serial/client/serial_main.c
+++ b/channels/serial/client/serial_main.c
@@ -584,6 +584,7 @@ void close_terminated_irp_thread_handles(SERIAL_DEVICE* serial, BOOL forceClose)
EnterCriticalSection(&serial->TerminatingIrpThreadsLock);
+ ListDictionary_Lock(serial->IrpThreads);
ULONG_PTR* ids = NULL;
const size_t nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids);
@@ -597,6 +598,7 @@ void close_terminated_irp_thread_handles(SERIAL_DEVICE* serial, BOOL forceClose)
}
free(ids);
+ ListDictionary_Unlock(serial->IrpThreads);
LeaveCriticalSection(&serial->TerminatingIrpThreadsLock);
}
@@ -650,19 +652,6 @@ static void create_irp_thread(SERIAL_DEVICE* serial, IRP* irp)
return;
}
- if (ListDictionary_Count(serial->IrpThreads) >= MAX_IRP_THREADS)
- {
- WLog_Print(serial->log, WLOG_WARN,
- "Number of IRP threads threshold reached: %" PRIuz ", keep on anyway",
- ListDictionary_Count(serial->IrpThreads));
- WINPR_ASSERT(FALSE); /* unimplemented */
- /* TODO: MAX_IRP_THREADS has been thought to avoid a
- * flooding of pending requests. Use
- * WaitForMultipleObjects() when available in winpr
- * for threads.
- */
- }
-
/* error_handle to be used ... */
data = (IRP_THREAD_DATA*)calloc(1, sizeof(IRP_THREAD_DATA));
@@ -685,7 +674,23 @@ static void create_irp_thread(SERIAL_DEVICE* serial, IRP* irp)
key = irp->CompletionId + 1ull;
- if (!ListDictionary_Add(serial->IrpThreads, (void*)key, irpThread))
+ ListDictionary_Lock(serial->IrpThreads);
+ if (ListDictionary_Count(serial->IrpThreads) >= MAX_IRP_THREADS)
+ {
+ WLog_Print(serial->log, WLOG_WARN,
+ "Number of IRP threads threshold reached: %" PRIuz ", keep on anyway",
+ ListDictionary_Count(serial->IrpThreads));
+ WINPR_ASSERT(FALSE); /* unimplemented */
+ /* TODO: MAX_IRP_THREADS has been thought to avoid a
+ * flooding of pending requests. Use
+ * WaitForMultipleObjects() when available in winpr
+ * for threads.
+ */
+ }
+ const BOOL added = ListDictionary_Add(serial->IrpThreads, (void*)key, irpThread);
+ ListDictionary_Unlock(serial->IrpThreads);
+
+ if (!added)
{
WLog_Print(serial->log, WLOG_ERROR, "ListDictionary_Add failed!");
goto error_handle;
@@ -966,7 +971,7 @@ FREERDP_ENTRY_POINT(
}
/* IrpThreads content only modified by create_irp_thread() */
- serial->IrpThreads = ListDictionary_New(FALSE);
+ serial->IrpThreads = ListDictionary_New(TRUE);
if (!serial->IrpThreads)
{
--
2.53.0

View File

@ -0,0 +1,24 @@
From 414f701464929c217f2509bcbd6d2c1f00f7ed73 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 11:07:25 +0100
Subject: [PATCH] [channels,urbdrc] cancel all usb transfers on channel close
---
channels/urbdrc/client/libusb/libusb_udevice.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c
index 5341248ec..9e2d3ec5a 100644
--- a/channels/urbdrc/client/libusb/libusb_udevice.c
+++ b/channels/urbdrc/client/libusb/libusb_udevice.c
@@ -1165,6 +1165,7 @@ static void libusb_udev_mark_channel_closed(IUDEVICE* idev)
const uint8_t devNr = idev->get_dev_number(idev);
pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
+ pdev->iface.cancel_all_transfer_request(&pdev->iface);
urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr);
}
}
--
2.53.0

View File

@ -0,0 +1,29 @@
From a304360d05cd2692ac4d87af017277d934863616 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 11:54:56 +0100
Subject: [PATCH] [channels,urbdrc] do not free MsConfig on failure
Backport of commit d676518809c319eec15911c705c13536036af2ae.
---
channels/urbdrc/client/data_transfer.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c
index 000ee2e1d..f6f366494 100644
--- a/channels/urbdrc/client/data_transfer.c
+++ b/channels/urbdrc/client/data_transfer.c
@@ -575,10 +575,8 @@ static UINT urb_select_interface(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callb
MsConfig = pdev->get_MsConfig(pdev);
InterfaceNumber = MsInterface->InterfaceNumber;
if (!msusb_msinterface_replace(MsConfig, InterfaceNumber, MsInterface))
- {
- msusb_msconfig_free(MsConfig);
return ERROR_BAD_CONFIGURATION;
- }
+
/* complete configuration setup */
if (!pdev->complete_msconfig_setup(pdev, MsConfig))
{
--
2.53.0

View File

@ -0,0 +1,42 @@
From 2d563a50be17c1b407ca448b1321378c0726dd31 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:59:39 +0100
Subject: [PATCH] [channels,urbdrc] ensure InterfaceNumber is within range
---
channels/urbdrc/client/libusb/libusb_udevice.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c
index 6c2376f74..5341248ec 100644
--- a/channels/urbdrc/client/libusb/libusb_udevice.c
+++ b/channels/urbdrc/client/libusb/libusb_udevice.c
@@ -539,19 +539,19 @@ static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BY
int error = 0;
int diff = 0;
UDEVICE* pdev = (UDEVICE*)idev;
- URBDRC_PLUGIN* urbdrc = NULL;
- MSUSB_CONFIG_DESCRIPTOR* MsConfig = NULL;
- MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL;
if (!pdev || !pdev->urbdrc)
return -1;
- urbdrc = pdev->urbdrc;
- MsConfig = pdev->MsConfig;
+ URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
+ MSUSB_CONFIG_DESCRIPTOR* MsConfig = pdev->MsConfig;
if (MsConfig)
{
- MsInterfaces = MsConfig->MsInterfaces;
+ if (InterfaceNumber >= MsConfig->NumInterfaces)
+ return -2;
+
+ MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces;
if (MsInterfaces)
{
WLog_Print(urbdrc->log, WLOG_INFO,
--
2.53.0

View File

@ -0,0 +1,37 @@
From bd3c5d3ab73cbe10ac3c079fb0b26610d3231133 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Thu, 26 Mar 2026 13:39:12 +0100
Subject: [PATCH] [channels,video] fix wrong cast
Backport of commit e01cd85c8003a245ef9778f0eda4b9235514c201.
Made-with: Cursor
---
channels/video/client/video_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/channels/video/client/video_main.c b/channels/video/client/video_main.c
index c2677992b..5177f6d0f 100644
--- a/channels/video/client/video_main.c
+++ b/channels/video/client/video_main.c
@@ -1005,7 +1005,7 @@ static UINT video_control_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
if (pChannelCallback)
{
- GENERIC_LISTENER_CALLBACK* listener_callback = (GENERIC_LISTENER_CALLBACK*)pChannelCallback;
+ GENERIC_CHANNEL_CALLBACK* listener_callback = (GENERIC_CHANNEL_CALLBACK*)pChannelCallback;
VIDEO_PLUGIN* video = (VIDEO_PLUGIN*)listener_callback->plugin;
if (video && video->control_callback)
{
@@ -1020,7 +1020,7 @@ static UINT video_data_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
if (pChannelCallback)
{
- GENERIC_LISTENER_CALLBACK* listener_callback = (GENERIC_LISTENER_CALLBACK*)pChannelCallback;
+ GENERIC_CHANNEL_CALLBACK* listener_callback = (GENERIC_CHANNEL_CALLBACK*)pChannelCallback;
VIDEO_PLUGIN* video = (VIDEO_PLUGIN*)listener_callback->plugin;
if (video && video->data_callback)
{
--
2.53.0

View File

@ -0,0 +1,117 @@
From 0328bb3828b836d53b904187b0b6d49f940d1180 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Thu, 26 Mar 2026 13:39:06 +0100
Subject: [PATCH] [channels,video] unify error handling
Partial backport of commit 635ae3c8193256db01774fab5ff11bcae57aed6b.
Made-with: Cursor
---
channels/video/client/video_main.c | 49 +++++++++++++++++++-----------
1 file changed, 32 insertions(+), 17 deletions(-)
diff --git a/channels/video/client/video_main.c b/channels/video/client/video_main.c
index 390f1723a..c2677992b 100644
--- a/channels/video/client/video_main.c
+++ b/channels/video/client/video_main.c
@@ -354,14 +354,24 @@ void VideoClientContextPriv_free(VideoClientContextPriv* priv)
free(priv);
}
+static UINT video_channel_write(VIDEO_PLUGIN* video, const BYTE* data, UINT32 length)
+{
+ WINPR_ASSERT(video);
+
+ if (!video->control_callback || !video->control_callback->channel_callback)
+ return ERROR_BAD_CONFIGURATION;
+ IWTSVirtualChannel* channel = video->control_callback->channel_callback->channel;
+ if (!channel || !channel->Write)
+ return ERROR_BAD_CONFIGURATION;
+ return channel->Write(channel, length, data, NULL);
+}
+
static UINT video_control_send_presentation_response(VideoClientContext* context,
TSMM_PRESENTATION_RESPONSE* resp)
{
BYTE buf[12] = { 0 };
wStream* s = NULL;
VIDEO_PLUGIN* video = NULL;
- IWTSVirtualChannel* channel = NULL;
- UINT ret = 0;
WINPR_ASSERT(context);
WINPR_ASSERT(resp);
@@ -379,11 +389,9 @@ static UINT video_control_send_presentation_response(VideoClientContext* context
Stream_Zero(s, 3);
Stream_SealLength(s);
- channel = video->control_callback->channel_callback->channel;
- ret = channel->Write(channel, 12, buf, NULL);
Stream_Free(s, FALSE);
- return ret;
+ return video_channel_write(video, buf, sizeof(buf));
}
static BOOL video_onMappedGeometryUpdate(MAPPED_GEOMETRY* geometry)
@@ -620,8 +628,6 @@ static UINT video_control_send_client_notification(VideoClientContext* context,
BYTE buf[100];
wStream* s = NULL;
VIDEO_PLUGIN* video = NULL;
- IWTSVirtualChannel* channel = NULL;
- UINT ret = 0;
UINT32 cbSize = 0;
WINPR_ASSERT(context);
@@ -661,16 +667,7 @@ static UINT video_control_send_client_notification(VideoClientContext* context,
Stream_Write_UINT32(s, cbSize);
Stream_Free(s, FALSE);
- WINPR_ASSERT(video->control_callback);
- WINPR_ASSERT(video->control_callback->channel_callback);
-
- channel = video->control_callback->channel_callback->channel;
- WINPR_ASSERT(channel);
- WINPR_ASSERT(channel->Write);
-
- ret = channel->Write(channel, cbSize, buf, NULL);
-
- return ret;
+ return video_channel_write(video, buf, cbSize);
}
static void video_timer(VideoClientContext* video, UINT64 now)
@@ -1006,12 +1003,30 @@ static UINT video_data_on_data_received(IWTSVirtualChannelCallback* pChannelCall
*/
static UINT video_control_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
+ if (pChannelCallback)
+ {
+ GENERIC_LISTENER_CALLBACK* listener_callback = (GENERIC_LISTENER_CALLBACK*)pChannelCallback;
+ VIDEO_PLUGIN* video = (VIDEO_PLUGIN*)listener_callback->plugin;
+ if (video && video->control_callback)
+ {
+ video->control_callback->channel_callback = NULL;
+ }
+ }
free(pChannelCallback);
return CHANNEL_RC_OK;
}
static UINT video_data_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
+ if (pChannelCallback)
+ {
+ GENERIC_LISTENER_CALLBACK* listener_callback = (GENERIC_LISTENER_CALLBACK*)pChannelCallback;
+ VIDEO_PLUGIN* video = (VIDEO_PLUGIN*)listener_callback->plugin;
+ if (video && video->data_callback)
+ {
+ video->data_callback->channel_callback = NULL;
+ }
+ }
free(pChannelCallback);
return CHANNEL_RC_OK;
}
--
2.53.0

View File

@ -0,0 +1,99 @@
From 1ea1d83a365f81628a2c38e9ec0223de6b975889 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 10 Mar 2026 13:00:04 +0100
Subject: [PATCH] [codec,color] add freerdp_glyph_convert_ex
Backport of commit 3bc1eeb4f63ceec9a696af194e4c1ea0e67ff60c.
Made-with: Cursor
---
libfreerdp/codec/color.c | 8 ++++++-
libfreerdp/gdi/graphics.c | 46 +++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c
index 9a2be6fc6..0db9573b8 100644
--- a/libfreerdp/codec/color.c
+++ b/libfreerdp/codec/color.c
@@ -50,7 +50,13 @@ BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height, const BYTE* WINPR_RESTR
* this approach uses a little more memory, but provides faster
* means of accessing individual pixels in blitting operations
*/
- const UINT32 scanline = (width + 7) / 8;
+ const size_t scanline = (width + 7ull) / 8ull;
+
+ if ((width == 0) || (height == 0))
+ return NULL;
+
+ WINPR_ASSERT(data);
+
BYTE* dstData = (BYTE*)winpr_aligned_malloc(1ull * width * height, 16);
if (!dstData)
diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c
index bcb9f9776..99aaab37a 100644
--- a/libfreerdp/gdi/graphics.c
+++ b/libfreerdp/gdi/graphics.c
@@ -21,6 +21,7 @@
#include <freerdp/config.h>
+#include <winpr/assert.h>
#include <winpr/crt.h>
#include <freerdp/log.h>
@@ -262,6 +263,51 @@ static BOOL gdi_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL p
}
/* Glyph Class */
+static BYTE* freerdp_glyph_convert_ex(UINT32 width, UINT32 height, const BYTE* WINPR_RESTRICT data,
+ size_t len)
+{
+ /*
+ * converts a 1-bit-per-pixel glyph to a one-byte-per-pixel glyph:
+ * this approach uses a little more memory, but provides faster
+ * means of accessing individual pixels in blitting operations
+ */
+ const size_t scanline = (width + 7ull) / 8ull;
+ const size_t required = scanline * height;
+ if (len < required)
+ return NULL;
+
+ if ((len == 0) || (width == 0) || (height == 0))
+ return NULL;
+
+ WINPR_ASSERT(data);
+
+ BYTE* dstData = (BYTE*)winpr_aligned_malloc(1ull * width * height, 16);
+
+ if (!dstData)
+ return NULL;
+
+ ZeroMemory(dstData, 1ULL * width * height);
+ BYTE* dstp = dstData;
+
+ for (UINT32 y = 0; y < height; y++)
+ {
+ const BYTE* srcp = &data[1ull * y * scanline];
+
+ for (UINT32 x = 0; x < width; x++)
+ {
+ if ((*srcp & (0x80 >> (x % 8))) != 0)
+ *dstp = 0xFF;
+
+ dstp++;
+
+ if (((x + 1) % 8 == 0) && x != 0)
+ srcp++;
+ }
+ }
+
+ return dstData;
+}
+
static BOOL gdi_Glyph_New(rdpContext* context, rdpGlyph* glyph)
{
BYTE* data = NULL;
--
2.53.0

View File

@ -0,0 +1,91 @@
From 7702ec2f2aadb0cfae86b00c177647e31f6159d4 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Mon, 30 Mar 2026 17:25:10 +0200
Subject: [PATCH] [codec,nsc] fix use of nsc_process_message
Backport of commit 169971607cece48384cb94632b829bd57336af0f.
Made-with: Cursor
---
libfreerdp/codec/clear.c | 10 ++++++----
libfreerdp/codec/nsc.c | 9 ++++++++-
libfreerdp/gdi/gdi.c | 4 ++--
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c
index 4c42bb2bf..a54758173 100644
--- a/libfreerdp/codec/clear.c
+++ b/libfreerdp/codec/clear.c
@@ -133,7 +133,8 @@ static BOOL convert_color(BYTE* WINPR_RESTRICT dst, UINT32 nDstStep, UINT32 DstF
static BOOL clear_decompress_nscodec(NSC_CONTEXT* WINPR_RESTRICT nsc, UINT32 width, UINT32 height,
wStream* WINPR_RESTRICT s, UINT32 bitmapDataByteCount,
BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat,
- UINT32 nDstStep, UINT32 nXDstRel, UINT32 nYDstRel)
+ UINT32 nDstStep, UINT32 nXDstRel, UINT32 nYDstRel,
+ UINT32 nDstWidth, UINT32 nDstHeight)
{
BOOL rc = 0;
@@ -141,8 +142,8 @@ static BOOL clear_decompress_nscodec(NSC_CONTEXT* WINPR_RESTRICT nsc, UINT32 wid
return FALSE;
rc = nsc_process_message(nsc, 32, width, height, Stream_Pointer(s), bitmapDataByteCount,
- pDstData, DstFormat, nDstStep, nXDstRel, nYDstRel, width, height,
- FREERDP_FLIP_NONE);
+ pDstData, DstFormat, nDstStep, nXDstRel, nYDstRel, nDstWidth,
+ nDstHeight, FREERDP_FLIP_NONE);
Stream_Seek(s, bitmapDataByteCount);
return rc;
}
@@ -531,7 +532,8 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* WINPR_RESTRICT clear,
case 1: /* NSCodec */
if (!clear_decompress_nscodec(clear->nsc, width, height, s, bitmapDataByteCount,
- pDstData, DstFormat, nDstStep, nXDstRel, nYDstRel))
+ pDstData, DstFormat, nDstStep, nXDstRel, nYDstRel,
+ nDstWidth, nDstHeight))
return FALSE;
break;
diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c
index 916e5ff8d..951983a1d 100644
--- a/libfreerdp/codec/nsc.c
+++ b/libfreerdp/codec/nsc.c
@@ -435,11 +435,18 @@ BOOL nsc_process_message(NSC_CONTEXT* WINPR_RESTRICT context, UINT16 bpp, UINT32
BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStride,
UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, UINT32 flip)
{
+ WINPR_ASSERT(context);
+ WINPR_ASSERT(context->priv);
+
wStream* s = NULL;
wStream sbuffer = { 0 };
BOOL ret = 0;
- if (!context || !data || !pDstData)
+ if (!data || !pDstData)
+ {
+ WLog_Print(context->priv->log, WLOG_ERROR, "Invalid argument: data=%p, pDstData=%p",
+ (const void*)data, (void*)pDstData);
return FALSE;
+ }
s = Stream_StaticConstInit(&sbuffer, data, length);
diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c
index f80ada8ae..6a18307c2 100644
--- a/libfreerdp/gdi/gdi.c
+++ b/libfreerdp/gdi/gdi.c
@@ -1101,8 +1101,8 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
if (!nsc_process_message(
context->codecs->nsc, cmd->bmp.bpp, cmd->bmp.width, cmd->bmp.height,
cmd->bmp.bitmapData, cmd->bmp.bitmapDataLength, gdi->primary_buffer, format,
- gdi->stride, cmdRect.left, cmdRect.top, cmdRect.right - cmdRect.left,
- cmdRect.bottom - cmdRect.top, FREERDP_FLIP_VERTICAL))
+ gdi->stride, cmdRect.left, cmdRect.top, (UINT32)gdi->width, (UINT32)gdi->height,
+ FREERDP_FLIP_VERTICAL))
{
WLog_ERR(TAG, "Failed to process NSCodec message");
goto out;
--
2.53.0

View File

@ -0,0 +1,48 @@
From 33e12b7cfb83875479822769ffd4fda799f294ff Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Mon, 16 Mar 2026 14:58:52 +0100
Subject: [PATCH] [codec,nsc] limit copy area in nsc_process_message
Backport of commit 83d9aedea278a74af3e490ff5eeb889c016dbb2b.
Made-with: Cursor
---
libfreerdp/codec/nsc.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c
index f7a5e920f..916e5ff8d 100644
--- a/libfreerdp/codec/nsc.c
+++ b/libfreerdp/codec/nsc.c
@@ -22,6 +22,7 @@
#include <freerdp/config.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -502,9 +503,17 @@ BOOL nsc_process_message(NSC_CONTEXT* WINPR_RESTRICT context, UINT16 bpp, UINT32
return FALSE;
}
- if (!freerdp_image_copy_no_overlap(pDstData, DstFormat, nDstStride, nXDst, nYDst, width, height,
- context->BitmapData, PIXEL_FORMAT_BGRA32, 0, 0, 0, NULL,
- flip))
+ uint32_t cwidth = width;
+ if (1ull * nXDst + width > nWidth)
+ cwidth = nWidth - nXDst;
+
+ uint32_t cheight = height;
+ if (1ull * nYDst + height > nHeight)
+ cheight = nHeight - nYDst;
+
+ if (!freerdp_image_copy_no_overlap(pDstData, DstFormat, nDstStride, nXDst, nYDst, cwidth,
+ cheight, context->BitmapData, PIXEL_FORMAT_BGRA32, 0, 0, 0,
+ NULL, flip))
return FALSE;
return TRUE;
--
2.53.0

View File

@ -0,0 +1,59 @@
From 51847b9d1c3a3720e4742d2a6ee92429f0c1af48 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 10 Mar 2026 14:53:37 +0100
Subject: [PATCH] [core,info] fix missing NULL check
Backport of commit 4d44e3c097656a8b9ec696353647b0888ca45860.
Made-with: Cursor
---
libfreerdp/core/info.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
index 2f8e6694c..08d11e286 100644
--- a/libfreerdp/core/info.c
+++ b/libfreerdp/core/info.c
@@ -1436,7 +1436,7 @@ static BOOL rdp_write_logon_info_v1(wStream* s, logon_info* info)
return TRUE;
}
-static BOOL rdp_write_logon_info_v2(wStream* s, logon_info* info)
+static BOOL rdp_write_logon_info_v2(wStream* s, const logon_info* info)
{
size_t domainLen = 0;
size_t usernameLen = 0;
@@ -1451,11 +1451,14 @@ static BOOL rdp_write_logon_info_v2(wStream* s, logon_info* info)
*/
Stream_Write_UINT32(s, logonInfoV2Size);
Stream_Write_UINT32(s, info->sessionId);
- domainLen = strnlen(info->domain, UINT32_MAX);
+ if (info->domain)
+ domainLen = strnlen(info->domain, UINT32_MAX);
if (domainLen >= UINT32_MAX / sizeof(WCHAR))
return FALSE;
Stream_Write_UINT32(s, (UINT32)(domainLen + 1) * sizeof(WCHAR));
- usernameLen = strnlen(info->username, UINT32_MAX);
+
+ if (info->username)
+ usernameLen = strnlen(info->username, UINT32_MAX);
if (usernameLen >= UINT32_MAX / sizeof(WCHAR))
return FALSE;
Stream_Write_UINT32(s, (UINT32)(usernameLen + 1) * sizeof(WCHAR));
@@ -1522,10 +1525,11 @@ static BOOL rdp_write_logon_info_ex(wStream* s, logon_info_ex* info)
BOOL rdp_send_save_session_info(rdpContext* context, UINT32 type, void* data)
{
- wStream* s = NULL;
BOOL status = 0;
+
+ WINPR_ASSERT(context);
rdpRdp* rdp = context->rdp;
- s = rdp_data_pdu_init(rdp);
+ wStream* s = rdp_data_pdu_init(rdp);
if (!s)
return FALSE;
--
2.53.0

View File

@ -30,7 +30,7 @@
Name: freerdp
Epoch: 2
Version: 3.10.3
Release: 5%{?dist}.3
Release: 5%{?dist}.5
Summary: Free implementation of the Remote Desktop Protocol (RDP)
# The effective license is Apache-2.0 but:
@ -105,6 +105,81 @@ Patch: codec-clear-fix-destination-checks.patch
# https://github.com/FreeRDP/FreeRDP/commit/a0be5cb87d760bb1c803ad1bb835aa1e73e62abc
Patch: codec-planar-fix-missing-destination-bounds-checks.patch
# CVE-2026-22852
# https://github.com/FreeRDP/FreeRDP/commit/cd1ffa112cfbe1b40a9fd57e299a8ea12e23df0d
Patch: channels-audin-free-up-old-audio-formats.patch
# CVE-2026-22854
# https://github.com/FreeRDP/FreeRDP/commit/3da319570c8a6be0a79b3306f1ed354c4a943259
Patch: channels-drive-fix-constant-type.patch
# CVE-2026-22856
# https://github.com/FreeRDP/FreeRDP/commit/b35aa3614d32bff3fc1272cd7c4617f711fca1a4
# https://github.com/FreeRDP/FreeRDP/commit/675c20f08f32ca5ec06297108bdf30147d6e2cd9
Patch: channels-serial-lock-list-dictionary.patch
Patch: channels-serial-explicitly-lock-serial-IrpThreads.patch
# CVE-2026-23732
# https://github.com/FreeRDP/FreeRDP/commit/3bc1eeb4f63ceec9a696af194e4c1ea0e67ff60c
# https://github.com/FreeRDP/FreeRDP/commit/9f0eb3b7d43069a1e973464bcb43d1ef965ae65e
Patch: codec-color-add-freerdp_glyph_convert_ex.patch
Patch: gdi-graphics-Use-freerdp_glyph_convert_ex.patch
# CVE-2026-23948
# https://github.com/FreeRDP/FreeRDP/commit/4d44e3c097656a8b9ec696353647b0888ca45860
Patch: core-info-fix-missing-NULL-check.patch
# CVE-2026-24491
# https://github.com/FreeRDP/FreeRDP/commit/e02e052f6692550e539d10f99de9c35a23492db2
# https://github.com/FreeRDP/FreeRDP/commit/cb7f295bc750de86480d60a3b58cebc56a57a1c4
# https://github.com/FreeRDP/FreeRDP/commit/635ae3c8193256db01774fab5ff11bcae57aed6b
# https://github.com/FreeRDP/FreeRDP/commit/e01cd85c8003a245ef9778f0eda4b9235514c201
Patch: channels-drdynvc-reset-channel_callback-before-close.patch
Patch: channels-drdynvc-check-pointer-before-reset.patch
Patch: channels-video-unify-error-handling.patch
Patch: channels-video-fix-wrong-cast.patch
# CVE-2026-24675
# https://github.com/FreeRDP/FreeRDP/commit/d676518809c319eec15911c705c13536036af2ae
Patch: channels-urbdrc-do-not-free-MsConfig-on-failure.patch
# CVE-2026-24676
# https://github.com/FreeRDP/FreeRDP/commit/026b81ae5831ac1598d8f7371e0d0996fac7db00
Patch: channels-audin-reset-audin-format.patch
# CVE-2026-24679
# https://github.com/FreeRDP/FreeRDP/commit/2d563a50be17c1b407ca448b1321378c0726dd31
Patch: channels-urbdrc-ensure-InterfaceNumber-is-within-ran.patch
# CVE-2026-24681
# https://github.com/FreeRDP/FreeRDP/commit/414f701464929c217f2509bcbd6d2c1f00f7ed73
Patch: channels-urbdrc-cancel-all-usb-transfers-on-channel-.patch
# CVE-2026-24682
# https://github.com/FreeRDP/FreeRDP/commit/1c5c74223179d425a1ce6dbbb6a3dd2a958b7aee
# https://github.com/FreeRDP/FreeRDP/commit/668352a2e241ba017679c11a22ecbe29d0b17401
Patch: channels-audin-fix-audin_server_recv_formats-cleanup.patch
Patch: channels-audin-set-error-when-audio_format_read-fail.patch
# CVE-2026-24683
# https://github.com/FreeRDP/FreeRDP/commit/d9ca272dce7a776ab475e9b1a8e8c3d2968c8486
Patch: channels-ainput-lock-context-when-updating-listener.patch
# CVE-2026-24684
# https://github.com/FreeRDP/FreeRDP/commit/622bb7b4402491ca003f47472d0e478132673696
# https://github.com/FreeRDP/FreeRDP/commit/afa6851dc80835d3101e40fcef51b6c5c0f43ea5
Patch: channels-rdpsnd-terminate-thread-before-free.patch
Patch: channel-rdpsnd-only-clean-up-thread-before-free.patch
# CVE-2026-31806
# https://github.com/FreeRDP/FreeRDP/commit/83d9aedea278a74af3e490ff5eeb889c016dbb2b
# https://github.com/FreeRDP/FreeRDP/commit/169971607cece48384cb94632b829bd57336af0f
Patch: codec-nsc-limit-copy-area-in-nsc_process_message.patch
Patch: codec-nsc-fix-use-of-nsc_process_message.patch
# https://github.com/FreeRDP/FreeRDP/commit/907ca47e40583a7788674bb2f06258edd0c34223
Patch: winpr-synch-increase-timeout-for-TestSynchCritical.patch
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: alsa-lib-devel
@ -427,6 +502,17 @@ find %{buildroot} -name "*.a" -delete
%{_libdir}/pkgconfig/winpr-tools3.pc
%changelog
* Tue Mar 31 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.5
- Fix use of nsc_process_message
- Increase timeout for TestSynchCritical
Resolves: RHEL-155979
* Fri Mar 27 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.4
- Backport several CVE fixes
Resolves: RHEL-147948, RHEL-147949, RHEL-147956, RHEL-147963, RHEL-147964
Resolves: RHEL-147972, RHEL-147979, RHEL-147984, RHEL-147985, RHEL-148898
Resolves: RHEL-148978, RHEL-148984, RHEL-149051, RHEL-155979
* Wed Mar 25 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.3
- Backport several CVE fixes
Resolves: RHEL-151975, RHEL-152202

View File

@ -0,0 +1,40 @@
From e1bbcba2ee4ba8bb20bb73b16717a2e5d491825b Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Sun, 29 Mar 2026 05:48:58 +0200
Subject: [PATCH] [gdi,graphics] Use freerdp_glyph_convert_ex
Backport of commit 9f0eb3b7d43069a1e973464bcb43d1ef965ae65e.
---
libfreerdp/gdi/graphics.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c
index 99aaab37a..eec5cd6b9 100644
--- a/libfreerdp/gdi/graphics.c
+++ b/libfreerdp/gdi/graphics.c
@@ -310,20 +310,17 @@ static BYTE* freerdp_glyph_convert_ex(UINT32 width, UINT32 height, const BYTE* W
static BOOL gdi_Glyph_New(rdpContext* context, rdpGlyph* glyph)
{
- BYTE* data = NULL;
- gdiGlyph* gdi_glyph = NULL;
-
if (!context || !glyph)
return FALSE;
- gdi_glyph = (gdiGlyph*)glyph;
+ gdiGlyph* gdi_glyph = (gdiGlyph*)glyph;
gdi_glyph->hdc = gdi_GetDC();
if (!gdi_glyph->hdc)
return FALSE;
gdi_glyph->hdc->format = PIXEL_FORMAT_MONO;
- data = freerdp_glyph_convert(glyph->cx, glyph->cy, glyph->aj);
+ BYTE* data = freerdp_glyph_convert_ex(glyph->cx, glyph->cy, glyph->aj, glyph->cb);
if (!data)
{
--
2.53.0

View File

@ -0,0 +1,30 @@
From 907ca47e40583a7788674bb2f06258edd0c34223 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Hor=C3=A1k?= <dan@danny.cz>
Date: Fri, 22 Aug 2025 19:14:05 +0200
Subject: [PATCH] [winpr,synch] increase timeout for TestSynchCritical
Increase the deadlock detection timeout in TestSynchCritical to accommodate
longer runtime on systems with large number of CPUs/threads. The usual test
run time when the threads are finishing correctly won't change.
Fixes: https://github.com/FreeRDP/FreeRDP/issues/11800
---
winpr/libwinpr/synch/test/TestSynchCritical.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/winpr/libwinpr/synch/test/TestSynchCritical.c b/winpr/libwinpr/synch/test/TestSynchCritical.c
index 139885a81..b44a70a1e 100644
--- a/winpr/libwinpr/synch/test/TestSynchCritical.c
+++ b/winpr/libwinpr/synch/test/TestSynchCritical.c
@@ -8,7 +8,7 @@
#include <winpr/thread.h>
#include <winpr/interlocked.h>
-#define TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS 50
+#define TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS 100
#define TEST_SYNC_CRITICAL_TEST1_RUNS 4
static CRITICAL_SECTION critical;
--
2.53.0