From 5f89d0213d5f7498fb2f7dc2f4a5daff33df1738 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Thu, 9 Apr 2026 16:40:48 +0200 Subject: [PATCH] Update to 3.24.2 Resolves: RHEL-80426 --- .gitignore | 1 + Default-minimum-thread-count.patch | 52 --- ...n-pointers-after-resource-allocation.patch | 64 ---- Limit-minimum-threadpool-size.patch | 51 --- Limit-threadpool-to-16-threads.patch | 60 ---- Use-default-threadpool.patch | 321 ------------------ ...screen-invalidate-bitmap-before-free.patch | 45 --- ...snd-only-clean-up-thread-before-free.patch | 117 ------- ...-lock-context-when-updating-listener.patch | 112 ------ ...ix-audin_server_recv_formats-cleanup.patch | 29 -- ...nels-audin-free-up-old-audio-formats.patch | 27 -- channels-audin-reset-audin-format.patch | 33 -- ...et-error-when-audio_format_read-fail.patch | 34 -- ...s-drdynvc-check-pointer-before-reset.patch | 33 -- ...-reset-channel_callback-before-close.patch | 35 -- channels-drive-fix-constant-type.patch | 26 -- channels-rdpear-add-checks-for-itemSize.patch | 69 ---- ...pecam-ensure-all-streams-are-stopped.patch | 27 -- ...-rdpsnd-terminate-thread-before-free.patch | 65 ---- ...al-explicitly-lock-serial-IrpThreads.patch | 47 --- channels-serial-lock-list-dictionary.patch | 87 ----- ...cancel-all-usb-transfers-on-channel-.patch | 24 -- ...c-check-interface-indices-before-use.patch | 197 ----------- ...bdrc-do-not-free-MsConfig-on-failure.patch | 29 -- ...ensure-InterfaceNumber-is-within-ran.patch | 42 --- channels-video-fix-wrong-cast.patch | 37 -- channels-video-unify-error-handling.patch | 117 ------- ...ouble-free-in-case-of-invalid-pointe.patch | 48 --- ...lear-check-clear_decomress-glyphData.patch | 78 ----- ...clear-fix-clear_resize_buffer-checks.patch | 62 ---- codec-clear-fix-destination-checks.patch | 42 --- codec-clear-fix-off-by-one-length-check.patch | 31 -- ...c-color-add-freerdp_glyph_convert_ex.patch | 99 ------ ...c-nsc-fix-use-of-nsc_process_message.patch | 91 ----- ...mit-copy-area-in-nsc_process_message.patch | 48 --- codec-planar-fix-decoder-length-checks.patch | 28 -- ...ix-missing-destination-bounds-checks.patch | 55 --- ...ection-print-SSL-warnings-after-init.patch | 37 -- core-info-fix-missing-NULL-check.patch | 59 ---- core-tcp-Don-t-ignore-connect-errors.patch | 43 --- ...ferIPv6OverIPv4-fallback-to-IPv4-add.patch | 102 ------ ...ry-next-DNS-entry-on-connect-failure.patch | 76 ----- ...fix-double-free-in-get_next_addrinfo.patch | 39 --- crypto-base64-ensure-char-is-singend.patch | 29 -- freerdp.spec | 151 +------- gdi-gfx-properly-clamp-SurfaceToSurface.patch | 48 --- ...raphics-Use-freerdp_glyph_convert_ex.patch | 40 --- sources | 2 +- ...smartcard-add-length-validity-checks.patch | 81 ----- ...crease-timeout-for-TestSynchCritical.patch | 30 -- 50 files changed, 9 insertions(+), 3091 deletions(-) delete mode 100644 Default-minimum-thread-count.patch delete mode 100644 Initialize-function-pointers-after-resource-allocation.patch delete mode 100644 Limit-minimum-threadpool-size.patch delete mode 100644 Limit-threadpool-to-16-threads.patch delete mode 100644 Use-default-threadpool.patch delete mode 100644 cache-offscreen-invalidate-bitmap-before-free.patch delete mode 100644 channel-rdpsnd-only-clean-up-thread-before-free.patch delete mode 100644 channels-ainput-lock-context-when-updating-listener.patch delete mode 100644 channels-audin-fix-audin_server_recv_formats-cleanup.patch delete mode 100644 channels-audin-free-up-old-audio-formats.patch delete mode 100644 channels-audin-reset-audin-format.patch delete mode 100644 channels-audin-set-error-when-audio_format_read-fail.patch delete mode 100644 channels-drdynvc-check-pointer-before-reset.patch delete mode 100644 channels-drdynvc-reset-channel_callback-before-close.patch delete mode 100644 channels-drive-fix-constant-type.patch delete mode 100644 channels-rdpear-add-checks-for-itemSize.patch delete mode 100644 channels-rdpecam-ensure-all-streams-are-stopped.patch delete mode 100644 channels-rdpsnd-terminate-thread-before-free.patch delete mode 100644 channels-serial-explicitly-lock-serial-IrpThreads.patch delete mode 100644 channels-serial-lock-list-dictionary.patch delete mode 100644 channels-urbdrc-cancel-all-usb-transfers-on-channel-.patch delete mode 100644 channels-urbdrc-check-interface-indices-before-use.patch delete mode 100644 channels-urbdrc-do-not-free-MsConfig-on-failure.patch delete mode 100644 channels-urbdrc-ensure-InterfaceNumber-is-within-ran.patch delete mode 100644 channels-video-fix-wrong-cast.patch delete mode 100644 channels-video-unify-error-handling.patch delete mode 100644 client-x11-fix-double-free-in-case-of-invalid-pointe.patch delete mode 100644 codec-clear-check-clear_decomress-glyphData.patch delete mode 100644 codec-clear-fix-clear_resize_buffer-checks.patch delete mode 100644 codec-clear-fix-destination-checks.patch delete mode 100644 codec-clear-fix-off-by-one-length-check.patch delete mode 100644 codec-color-add-freerdp_glyph_convert_ex.patch delete mode 100644 codec-nsc-fix-use-of-nsc_process_message.patch delete mode 100644 codec-nsc-limit-copy-area-in-nsc_process_message.patch delete mode 100644 codec-planar-fix-decoder-length-checks.patch delete mode 100644 codec-planar-fix-missing-destination-bounds-checks.patch delete mode 100644 core-connection-print-SSL-warnings-after-init.patch delete mode 100644 core-info-fix-missing-NULL-check.patch delete mode 100644 core-tcp-Don-t-ignore-connect-errors.patch delete mode 100644 core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch delete mode 100644 core-tcp-Try-next-DNS-entry-on-connect-failure.patch delete mode 100644 core-tcp-fix-double-free-in-get_next_addrinfo.patch delete mode 100644 crypto-base64-ensure-char-is-singend.patch delete mode 100644 gdi-gfx-properly-clamp-SurfaceToSurface.patch delete mode 100644 gdi-graphics-Use-freerdp_glyph_convert_ex.patch delete mode 100644 utils-smartcard-add-length-validity-checks.patch delete mode 100644 winpr-synch-increase-timeout-for-TestSynchCritical.patch diff --git a/.gitignore b/.gitignore index 4e909b4..1d15d47 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,4 @@ /FreeRDP-3.8.0-repack.tar.gz /FreeRDP-3.9.0-repack.tar.gz /FreeRDP-3.10.3-repack.tar.gz +/FreeRDP-3.24.2-repack.tar.gz diff --git a/Default-minimum-thread-count.patch b/Default-minimum-thread-count.patch deleted file mode 100644 index 497f992..0000000 --- a/Default-minimum-thread-count.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0e6c921b206259474b1c14bb26b183a8b2089cdb Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Fri, 12 Sep 2025 08:25:16 +0200 -Subject: [PATCH 082/100] [winpr,threadpool] default minimum thread count - -Set a default minimum of 4 threads in a pool. Avoids issues with system -running with a single processor (might lead to deadlocks if the code -assumes > 1 thread handling stuff) ---- - winpr/libwinpr/pool/CMakeLists.txt | 2 ++ - winpr/libwinpr/pool/pool.c | 9 +++++++-- - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/winpr/libwinpr/pool/CMakeLists.txt b/winpr/libwinpr/pool/CMakeLists.txt -index cfa9bc891..6b5938fd0 100644 ---- a/winpr/libwinpr/pool/CMakeLists.txt -+++ b/winpr/libwinpr/pool/CMakeLists.txt -@@ -16,7 +16,9 @@ - # limitations under the License. - - set(WINPR_THREADPOOL_DEFAULT_MAX_COUNT "16" CACHE STRING "The maximum (default) number of threads in a pool") -+set(WINPR_THREADPOOL_DEFAULT_MIN_COUNT "4" CACHE STRING "The minimum (default) number of threads in a pool") - winpr_definition_add(WINPR_THREADPOOL_DEFAULT_MAX_COUNT=${WINPR_THREADPOOL_DEFAULT_MAX_COUNT}) -+winpr_definition_add(WINPR_THREADPOOL_DEFAULT_MIN_COUNT=${WINPR_THREADPOOL_DEFAULT_MIN_COUNT}) - winpr_module_add( - synch.c - work.c -diff --git a/winpr/libwinpr/pool/pool.c b/winpr/libwinpr/pool/pool.c -index 96db6b247..cbfc274c5 100644 ---- a/winpr/libwinpr/pool/pool.c -+++ b/winpr/libwinpr/pool/pool.c -@@ -127,10 +127,15 @@ static BOOL InitializeThreadpool(PTP_POOL pool) - obj = ArrayList_Object(pool->Threads); - obj->fnObjectFree = threads_close; - -+#if !defined(WINPR_THREADPOOL_DEFAULT_MIN_COUNT) -+#error "WINPR_THREADPOOL_DEFAULT_MIN_COUNT must be defined" -+#endif -+ - SYSTEM_INFO info = { 0 }; - GetSystemInfo(&info); -- if (info.dwNumberOfProcessors < 1) -- info.dwNumberOfProcessors = 1; -+ if (info.dwNumberOfProcessors < WINPR_THREADPOOL_DEFAULT_MIN_COUNT) -+ info.dwNumberOfProcessors = WINPR_THREADPOOL_DEFAULT_MIN_COUNT; -+ - if (!SetThreadpoolThreadMinimum(pool, info.dwNumberOfProcessors)) - goto fail; - --- -2.51.0 - diff --git a/Initialize-function-pointers-after-resource-allocation.patch b/Initialize-function-pointers-after-resource-allocation.patch deleted file mode 100644 index ecda3b8..0000000 --- a/Initialize-function-pointers-after-resource-allocation.patch +++ /dev/null @@ -1,64 +0,0 @@ -From a4bb702aa62e4fad91ca99142de075265555ec18 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Tue, 13 May 2025 10:34:08 +0200 -Subject: [PATCH] transport: Initialize function pointers after resource - allocation - -The transport instance is freed when an error occurs. -If the TransportDisconnect function pointer is initialized it -causes SIGSEGV during free. - -CVE: CVE-2025-4478 ---- - libfreerdp/core/transport.c | 28 ++++++++++++++-------------- - 1 file changed, 14 insertions(+), 14 deletions(-) - -diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c -index d199c31be..2ca146f65 100644 ---- a/libfreerdp/core/transport.c -+++ b/libfreerdp/core/transport.c -@@ -1646,20 +1646,6 @@ rdpTransport* transport_new(rdpContext* context) - if (!transport->log) - goto fail; - -- // transport->io.DataHandler = transport_data_handler; -- transport->io.TCPConnect = freerdp_tcp_default_connect; -- transport->io.TLSConnect = transport_default_connect_tls; -- transport->io.TLSAccept = transport_default_accept_tls; -- transport->io.TransportAttach = transport_default_attach; -- transport->io.TransportDisconnect = transport_default_disconnect; -- transport->io.ReadPdu = transport_default_read_pdu; -- transport->io.WritePdu = transport_default_write; -- transport->io.ReadBytes = transport_read_layer; -- transport->io.GetPublicKey = transport_default_get_public_key; -- transport->io.SetBlockingMode = transport_default_set_blocking_mode; -- transport->io.ConnectLayer = transport_default_connect_layer; -- transport->io.AttachLayer = transport_default_attach_layer; -- - transport->context = context; - transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE); - -@@ -1698,6 +1684,20 @@ rdpTransport* transport_new(rdpContext* context) - if (!InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000)) - goto fail; - -+ // transport->io.DataHandler = transport_data_handler; -+ transport->io.TCPConnect = freerdp_tcp_default_connect; -+ transport->io.TLSConnect = transport_default_connect_tls; -+ transport->io.TLSAccept = transport_default_accept_tls; -+ transport->io.TransportAttach = transport_default_attach; -+ transport->io.TransportDisconnect = transport_default_disconnect; -+ transport->io.ReadPdu = transport_default_read_pdu; -+ transport->io.WritePdu = transport_default_write; -+ transport->io.ReadBytes = transport_read_layer; -+ transport->io.GetPublicKey = transport_default_get_public_key; -+ transport->io.SetBlockingMode = transport_default_set_blocking_mode; -+ transport->io.ConnectLayer = transport_default_connect_layer; -+ transport->io.AttachLayer = transport_default_attach_layer; -+ - return transport; - fail: - WINPR_PRAGMA_DIAG_PUSH --- -2.49.0 - diff --git a/Limit-minimum-threadpool-size.patch b/Limit-minimum-threadpool-size.patch deleted file mode 100644 index a007bc9..0000000 --- a/Limit-minimum-threadpool-size.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 8fc7acbfd0a1892bc9237ae25e99d32270812dcc Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Mon, 29 Sep 2025 08:37:06 +0200 -Subject: [PATCH] [winpr,pool] limit minimum threadpool size - ---- - winpr/libwinpr/pool/pool.c | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/winpr/libwinpr/pool/pool.c b/winpr/libwinpr/pool/pool.c -index cbfc274c5..2cbe9a4fa 100644 ---- a/winpr/libwinpr/pool/pool.c -+++ b/winpr/libwinpr/pool/pool.c -@@ -129,22 +129,26 @@ static BOOL InitializeThreadpool(PTP_POOL pool) - - #if !defined(WINPR_THREADPOOL_DEFAULT_MIN_COUNT) - #error "WINPR_THREADPOOL_DEFAULT_MIN_COUNT must be defined" -+#endif -+#if !defined(WINPR_THREADPOOL_DEFAULT_MAX_COUNT) -+#error "WINPR_THREADPOOL_DEFAULT_MAX_COUNT must be defined" - #endif - - SYSTEM_INFO info = { 0 }; - GetSystemInfo(&info); -+ -+ DWORD min = info.dwNumberOfProcessors; -+ DWORD max = info.dwNumberOfProcessors; - if (info.dwNumberOfProcessors < WINPR_THREADPOOL_DEFAULT_MIN_COUNT) -- info.dwNumberOfProcessors = WINPR_THREADPOOL_DEFAULT_MIN_COUNT; -+ min = WINPR_THREADPOOL_DEFAULT_MIN_COUNT; -+ if (info.dwNumberOfProcessors > WINPR_THREADPOOL_DEFAULT_MAX_COUNT) -+ max = WINPR_THREADPOOL_DEFAULT_MAX_COUNT; -+ if (min > max) -+ min = max; - -- if (!SetThreadpoolThreadMinimum(pool, info.dwNumberOfProcessors)) -+ if (!SetThreadpoolThreadMinimum(pool, min)) - goto fail; - --#if !defined(WINPR_THREADPOOL_DEFAULT_MAX_COUNT) --#error "WINPR_THREADPOOL_DEFAULT_MAX_COUNT must be defined" --#endif -- DWORD max = info.dwNumberOfProcessors; -- if (max > WINPR_THREADPOOL_DEFAULT_MAX_COUNT) -- max = WINPR_THREADPOOL_DEFAULT_MAX_COUNT; - SetThreadpoolThreadMaximum(pool, max); - - rc = TRUE; --- -2.51.0 - diff --git a/Limit-threadpool-to-16-threads.patch b/Limit-threadpool-to-16-threads.patch deleted file mode 100644 index 3b2ec74..0000000 --- a/Limit-threadpool-to-16-threads.patch +++ /dev/null @@ -1,60 +0,0 @@ -From c2fc455d8f2dc60de35ed98cb300b7e6a84fe383 Mon Sep 17 00:00:00 2001 -From: Armin Novak -Date: Wed, 3 Sep 2025 14:03:10 +0200 -Subject: [PATCH 066/100] [winpr,pool] limit threadpool to 16 threads by - default - -Initialize the threadpool to minimum of number of processors and 16 by -default. ---- - winpr/libwinpr/pool/CMakeLists.txt | 2 ++ - winpr/libwinpr/pool/pool.c | 13 +++++++++---- - 2 files changed, 11 insertions(+), 4 deletions(-) - -diff --git a/winpr/libwinpr/pool/CMakeLists.txt b/winpr/libwinpr/pool/CMakeLists.txt -index fb2dee58f..cfa9bc891 100644 ---- a/winpr/libwinpr/pool/CMakeLists.txt -+++ b/winpr/libwinpr/pool/CMakeLists.txt -@@ -15,6 +15,8 @@ - # See the License for the specific language governing permissions and - # limitations under the License. - -+set(WINPR_THREADPOOL_DEFAULT_MAX_COUNT "16" CACHE STRING "The maximum (default) number of threads in a pool") -+winpr_definition_add(WINPR_THREADPOOL_DEFAULT_MAX_COUNT=${WINPR_THREADPOOL_DEFAULT_MAX_COUNT}) - winpr_module_add( - synch.c - work.c -diff --git a/winpr/libwinpr/pool/pool.c b/winpr/libwinpr/pool/pool.c -index 39bbaaac9..96db6b247 100644 ---- a/winpr/libwinpr/pool/pool.c -+++ b/winpr/libwinpr/pool/pool.c -@@ -133,7 +133,14 @@ static BOOL InitializeThreadpool(PTP_POOL pool) - info.dwNumberOfProcessors = 1; - if (!SetThreadpoolThreadMinimum(pool, info.dwNumberOfProcessors)) - goto fail; -- SetThreadpoolThreadMaximum(pool, info.dwNumberOfProcessors); -+ -+#if !defined(WINPR_THREADPOOL_DEFAULT_MAX_COUNT) -+#error "WINPR_THREADPOOL_DEFAULT_MAX_COUNT must be defined" -+#endif -+ DWORD max = info.dwNumberOfProcessors; -+ if (max > WINPR_THREADPOOL_DEFAULT_MAX_COUNT) -+ max = WINPR_THREADPOOL_DEFAULT_MAX_COUNT; -+ SetThreadpoolThreadMaximum(pool, max); - - rc = TRUE; - -@@ -143,9 +150,7 @@ fail: - - PTP_POOL GetDefaultThreadpool(void) - { -- PTP_POOL pool = NULL; -- -- pool = &DEFAULT_POOL; -+ PTP_POOL pool = &DEFAULT_POOL; - - if (!InitializeThreadpool(pool)) - return NULL; --- -2.51.0 - diff --git a/Use-default-threadpool.patch b/Use-default-threadpool.patch deleted file mode 100644 index d3940e3..0000000 --- a/Use-default-threadpool.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 00968fd6e647af286e67bbd616168c4de7a39208 Mon Sep 17 00:00:00 2001 -From: Armin Novak -Date: Wed, 3 Sep 2025 14:40:47 +0200 -Subject: [PATCH 067/100] [codec] use default threadpool - -Backported together with these commits to be applicable: - [codec,yuv] fix thread count calculation - - 17315c593655d476cccfb9a1b56e41f37030f8e1 - [codec,yuv] fix worker object handling - - 1cc64eb58b2f5ce9e4ad8aa8610e085f696e578c - Fix YUV conversion for systems with lots of CPUs - - 774ee652a9c73c0bc3cdba26eba0c112f079cee4 - ---- - libfreerdp/codec/progressive.c | 5 ++- - libfreerdp/codec/rfx.c | 56 +++++++--------------------------- - libfreerdp/codec/rfx_types.h | 6 ---- - libfreerdp/codec/yuv.c | 32 ++----------------- - 4 files changed, 16 insertions(+), 83 deletions(-) - -diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c -index 6396e0f2a..8b5200546 100644 ---- a/libfreerdp/codec/progressive.c -+++ b/libfreerdp/codec/progressive.c -@@ -1698,9 +1698,8 @@ static INLINE SSIZE_T progressive_process_tiles( - - if (progressive->rfx_context->priv->UseThreads) - { -- progressive->work_objects[idx] = -- CreateThreadpoolWork(progressive_process_tiles_tile_work_callback, (void*)param, -- &progressive->rfx_context->priv->ThreadPoolEnv); -+ progressive->work_objects[idx] = CreateThreadpoolWork( -+ progressive_process_tiles_tile_work_callback, (void*)param, NULL); - if (!progressive->work_objects[idx]) - { - WLog_Print(progressive->log, WLOG_ERROR, -diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c -index 8832cd740..2ec4eb521 100644 ---- a/libfreerdp/codec/rfx.c -+++ b/libfreerdp/codec/rfx.c -@@ -205,16 +205,8 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) - - RFX_CONTEXT* rfx_context_new_ex(BOOL encoder, UINT32 ThreadingFlags) - { -- HKEY hKey = NULL; -- LONG status = 0; -- DWORD dwType = 0; -- DWORD dwSize = 0; -- DWORD dwValue = 0; -- SYSTEM_INFO sysinfo; -- RFX_CONTEXT* context = NULL; -- wObject* pool = NULL; - RFX_CONTEXT_PRIV* priv = NULL; -- context = (RFX_CONTEXT*)winpr_aligned_calloc(1, sizeof(RFX_CONTEXT), 32); -+ RFX_CONTEXT* context = (RFX_CONTEXT*)winpr_aligned_calloc(1, sizeof(RFX_CONTEXT), 32); - - if (!context) - return NULL; -@@ -233,7 +225,7 @@ RFX_CONTEXT* rfx_context_new_ex(BOOL encoder, UINT32 ThreadingFlags) - if (!priv->TilePool) - goto fail; - -- pool = ObjectPool_Object(priv->TilePool); -+ wObject* pool = ObjectPool_Object(priv->TilePool); - pool->fnObjectInit = rfx_tile_init; - - if (context->encoder) -@@ -267,29 +259,22 @@ RFX_CONTEXT* rfx_context_new_ex(BOOL encoder, UINT32 ThreadingFlags) - - if (!(ThreadingFlags & THREADING_FLAGS_DISABLE_THREADS)) - { -+ HKEY hKey = NULL; - priv->UseThreads = TRUE; - -- GetNativeSystemInfo(&sysinfo); -- priv->MinThreadCount = sysinfo.dwNumberOfProcessors; -- priv->MaxThreadCount = 0; -- status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, RFX_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); -+ const LONG status = -+ RegOpenKeyExA(HKEY_LOCAL_MACHINE, RFX_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); - - if (status == ERROR_SUCCESS) - { -- dwSize = sizeof(dwValue); -+ DWORD dwType = 0; -+ DWORD dwValue = 0; -+ DWORD dwSize = sizeof(dwValue); - - if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*)&dwValue, &dwSize) == - ERROR_SUCCESS) - priv->UseThreads = dwValue ? 1 : 0; - -- if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*)&dwValue, -- &dwSize) == ERROR_SUCCESS) -- priv->MinThreadCount = dwValue; -- -- if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*)&dwValue, -- &dwSize) == ERROR_SUCCESS) -- priv->MaxThreadCount = dwValue; -- - RegCloseKey(hKey); - } - } -@@ -304,20 +289,6 @@ RFX_CONTEXT* rfx_context_new_ex(BOOL encoder, UINT32 ThreadingFlags) - /* from multiple threads. This call will initialize all function pointers correctly */ - /* before any decoding threads are started */ - primitives_get(); -- priv->ThreadPool = CreateThreadpool(NULL); -- -- if (!priv->ThreadPool) -- goto fail; -- -- InitializeThreadpoolEnvironment(&priv->ThreadPoolEnv); -- SetThreadpoolCallbackPool(&priv->ThreadPoolEnv, priv->ThreadPool); -- -- if (priv->MinThreadCount) -- if (!SetThreadpoolThreadMinimum(priv->ThreadPool, priv->MinThreadCount)) -- goto fail; -- -- if (priv->MaxThreadCount) -- SetThreadpoolThreadMaximum(priv->ThreadPool, priv->MaxThreadCount); - } - - /* initialize the default pixel format */ -@@ -370,9 +341,6 @@ void rfx_context_free(RFX_CONTEXT* context) - ObjectPool_Free(priv->TilePool); - if (priv->UseThreads) - { -- if (priv->ThreadPool) -- CloseThreadpool(priv->ThreadPool); -- DestroyThreadpoolEnvironment(&priv->ThreadPoolEnv); - winpr_aligned_free((void*)priv->workObjects); - winpr_aligned_free(priv->tileWorkParams); - #ifdef WITH_PROFILER -@@ -1086,9 +1054,8 @@ static INLINE BOOL rfx_process_message_tileset(RFX_CONTEXT* WINPR_RESTRICT conte - params[i].context = context; - params[i].tile = message->tiles[i]; - -- if (!(work_objects[i] = -- CreateThreadpoolWork(rfx_process_message_tile_work_callback, -- (void*)¶ms[i], &context->priv->ThreadPoolEnv))) -+ if (!(work_objects[i] = CreateThreadpoolWork(rfx_process_message_tile_work_callback, -+ (void*)¶ms[i], NULL))) - { - WLog_Print(context->priv->log, WLOG_ERROR, "CreateThreadpoolWork failed."); - rc = FALSE; -@@ -1829,8 +1796,7 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* WINPR_RESTRICT context, - workParam->tile = tile; - - if (!(*workObject = CreateThreadpoolWork(rfx_compose_message_tile_work_callback, -- (void*)workParam, -- &context->priv->ThreadPoolEnv))) -+ (void*)workParam, NULL))) - { - goto skip_encoding_loop; - } -diff --git a/libfreerdp/codec/rfx_types.h b/libfreerdp/codec/rfx_types.h -index a9cd314da..c5a62259b 100644 ---- a/libfreerdp/codec/rfx_types.h -+++ b/libfreerdp/codec/rfx_types.h -@@ -69,11 +69,11 @@ struct S_RFX_CONTEXT_PRIV - PTP_WORK* workObjects; - RFX_TILE_COMPOSE_WORK_PARAM* tileWorkParams; - -- DWORD MinThreadCount; -+ DWORD MinThreadCount; /* Kept only to silence abidiff */ -- DWORD MaxThreadCount; -+ DWORD MaxThreadCount; /* Kept only to silence abidiff */ - -- PTP_POOL ThreadPool; -+ PTP_POOL ThreadPool; /* Kept only to silence abidiff */ -- TP_CALLBACK_ENVIRON ThreadPoolEnv; -+ TP_CALLBACK_ENVIRON ThreadPoolEnv; /* Kept only to silence abidiff */ - - wBufferPool* BufferPool; - -diff --git a/libfreerdp/codec/yuv.c b/libfreerdp/codec/yuv.c -index 75d8a6a89..4025782dd 100644 ---- a/libfreerdp/codec/yuv.c -+++ b/libfreerdp/codec/yuv.c -@@ -55,11 +55,11 @@ struct S_YUV_CONTEXT - UINT32 width, height; - BOOL useThreads; - BOOL encoder; -- UINT32 nthreads; -+ UINT32 nthreads; /* Kept only to silence abidiff */ - UINT32 heightStep; - -- PTP_POOL threadPool; -+ PTP_POOL threadPool; /* Kept only to silence abidiff */ -- TP_CALLBACK_ENVIRON ThreadPoolEnv; -+ TP_CALLBACK_ENVIRON ThreadPoolEnv; /* Kept only to silence abidiff */ - - UINT32 work_object_count; - PTP_WORK* work_objects; -@@ -166,16 +162,21 @@ BOOL yuv_context_reset(YUV_CONTEXT* WINPR_RESTRICT context, UINT32 width, UINT32 - - context->width = width; - context->height = height; -- context->heightStep = (height / context->nthreads); -+ -+ context->heightStep = height; - - if (context->useThreads) - { -- const UINT32 pw = (width + TILE_SIZE - width % TILE_SIZE) / TILE_SIZE; -- const UINT32 ph = (height + TILE_SIZE - height % TILE_SIZE) / TILE_SIZE; -+ context->heightStep = 16; -+ /* Preallocate workers for 16x16 tiles. -+ * this is overallocation for most cases. -+ * -+ * ~2MB total for a 4k resolution, so negligible. -+ */ -+ const size_t pw = (width + TILE_SIZE - width % TILE_SIZE) / 16; -+ const size_t ph = (height + TILE_SIZE - height % TILE_SIZE) / 16; - -- /* We´ve calculated the amount of workers for 64x64 tiles, but the decoder -- * might get 16x16 tiles mixed in. */ -- const UINT32 count = pw * ph * 16; -+ const size_t count = pw * ph; - - context->work_object_count = 0; - if (context->encoder) -@@ -237,33 +234,13 @@ YUV_CONTEXT* yuv_context_new(BOOL encoder, UINT32 ThreadingFlags) - primitives_get(); - - ret->encoder = encoder; -- ret->nthreads = 1; - if (!(ThreadingFlags & THREADING_FLAGS_DISABLE_THREADS)) - { - GetNativeSystemInfo(&sysInfos); - ret->useThreads = (sysInfos.dwNumberOfProcessors > 1); -- if (ret->useThreads) -- { -- ret->nthreads = sysInfos.dwNumberOfProcessors; -- ret->threadPool = CreateThreadpool(NULL); -- if (!ret->threadPool) -- { -- goto error_threadpool; -- } -- -- InitializeThreadpoolEnvironment(&ret->ThreadPoolEnv); -- SetThreadpoolCallbackPool(&ret->ThreadPoolEnv, ret->threadPool); -- } - } - - return ret; -- --error_threadpool: -- WINPR_PRAGMA_DIAG_PUSH -- WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC -- yuv_context_free(ret); -- WINPR_PRAGMA_DIAG_POP -- return NULL; - } - - void yuv_context_free(YUV_CONTEXT* context) -@@ -272,9 +249,6 @@ void yuv_context_free(YUV_CONTEXT* context) - return; - if (context->useThreads) - { -- if (context->threadPool) -- CloseThreadpool(context->threadPool); -- DestroyThreadpoolEnvironment(&context->ThreadPoolEnv); - winpr_aligned_free((void*)context->work_objects); - winpr_aligned_free(context->work_combined_params); - winpr_aligned_free(context->work_enc_params); -@@ -330,7 +304,7 @@ static BOOL submit_object(PTP_WORK* WINPR_RESTRICT work_object, PTP_WORK_CALLBAC - if (!param || !context) - return FALSE; - -- *work_object = CreateThreadpoolWork(cb, cnv.pv, &context->ThreadPoolEnv); -+ *work_object = CreateThreadpoolWork(cb, cnv.pv, NULL); - if (!*work_object) - return FALSE; - -@@ -439,11 +417,8 @@ static BOOL pool_decode(YUV_CONTEXT* WIN - - if (context->work_object_count <= waitCount) - { -- WLog_ERR(TAG, -- "YUV decoder: invalid number of tiles, only support less than %" PRIu32 -- ", got %" PRIu32, -- context->work_object_count, waitCount); -- goto fail; -+ free_objects(context->work_objects, context->work_object_count); -+ waitCount = 0; - } - - YUV_PROCESS_WORK_PARAM* cur = &context->work_dec_params[waitCount]; -@@ -586,11 +561,8 @@ static BOOL pool_decode_rect(YUV_CONTEXT - - if (context->work_object_count <= waitCount) - { -- WLog_ERR(TAG, -- "YUV rect decoder: invalid number of tiles, only support less than %" PRIu32 -- ", got %" PRIu32, -- context->work_object_count, waitCount); -- goto fail; -+ free_objects(context->work_objects, context->work_object_count); -+ waitCount = 0; - } - current = &context->work_combined_params[waitCount]; - *current = pool_decode_rect_param(®ionRects[waitCount], context, type, pYUVData, iStride, -@@ -848,11 +820,8 @@ static BOOL pool_encode(YUV_CONTEXT* WIN - - if (context->work_object_count <= waitCount) - { -- WLog_ERR(TAG, -- "YUV encoder: invalid number of tiles, only support less than %" PRIu32 -- ", got %" PRIu32, -- context->work_object_count, waitCount); -- goto fail; -+ free_objects(context->work_objects, context->work_object_count); -+ waitCount = 0; - } - - current = &context->work_enc_params[waitCount]; --- -2.51.0 - diff --git a/cache-offscreen-invalidate-bitmap-before-free.patch b/cache-offscreen-invalidate-bitmap-before-free.patch deleted file mode 100644 index 26527c0..0000000 --- a/cache-offscreen-invalidate-bitmap-before-free.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 52106a26726a2aba77aa6d86014d2eb3507f0783 Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Mon, 19 Jan 2026 08:58:22 +0100 -Subject: [PATCH] [cache,offscreen] invalidate bitmap before free - -First ensure the bitmap is no longer used for drawing before calling the -free function. ---- - libfreerdp/cache/offscreen.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/libfreerdp/cache/offscreen.c b/libfreerdp/cache/offscreen.c -index 91fa38f32..d3c85f95d 100644 ---- a/libfreerdp/cache/offscreen.c -+++ b/libfreerdp/cache/offscreen.c -@@ -164,8 +164,6 @@ void offscreen_cache_put(rdpOffscreenCache* offscreenCache, UINT32 index, rdpBit - - void offscreen_cache_delete(rdpOffscreenCache* offscreenCache, UINT32 index) - { -- rdpBitmap* prevBitmap = NULL; -- - WINPR_ASSERT(offscreenCache); - - if (index >= offscreenCache->maxEntries) -@@ -174,10 +172,16 @@ void offscreen_cache_delete(rdpOffscreenCache* offscreenCache, UINT32 index) - return; - } - -- prevBitmap = offscreenCache->entries[index]; -+ rdpBitmap* prevBitmap = offscreenCache->entries[index]; - - if (prevBitmap != NULL) -+ { -+ WINPR_ASSERT(offscreenCache->context); -+ -+ /* Ensure that the bitmap is no longer used in GDI */ -+ IFCALL(prevBitmap->SetSurface, offscreenCache->context, NULL, FALSE); - Bitmap_Free(offscreenCache->context, prevBitmap); -+ } - - offscreenCache->entries[index] = NULL; - } --- -2.52.0 - diff --git a/channel-rdpsnd-only-clean-up-thread-before-free.patch b/channel-rdpsnd-only-clean-up-thread-before-free.patch deleted file mode 100644 index 46c4d08..0000000 --- a/channel-rdpsnd-only-clean-up-thread-before-free.patch +++ /dev/null @@ -1,117 +0,0 @@ -From afa6851dc80835d3101e40fcef51b6c5c0f43ea5 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-ainput-lock-context-when-updating-listener.patch b/channels-ainput-lock-context-when-updating-listener.patch deleted file mode 100644 index 5c83025..0000000 --- a/channels-ainput-lock-context-when-updating-listener.patch +++ /dev/null @@ -1,112 +0,0 @@ -From d9ca272dce7a776ab475e9b1a8e8c3d2968c8486 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-audin-fix-audin_server_recv_formats-cleanup.patch b/channels-audin-fix-audin_server_recv_formats-cleanup.patch deleted file mode 100644 index b153ab9..0000000 --- a/channels-audin-fix-audin_server_recv_formats-cleanup.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 1c5c74223179d425a1ce6dbbb6a3dd2a958b7aee Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-audin-free-up-old-audio-formats.patch b/channels-audin-free-up-old-audio-formats.patch deleted file mode 100644 index b3ccc0b..0000000 --- a/channels-audin-free-up-old-audio-formats.patch +++ /dev/null @@ -1,27 +0,0 @@ -From cd1ffa112cfbe1b40a9fd57e299a8ea12e23df0d Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-audin-reset-audin-format.patch b/channels-audin-reset-audin-format.patch deleted file mode 100644 index f604ed3..0000000 --- a/channels-audin-reset-audin-format.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 026b81ae5831ac1598d8f7371e0d0996fac7db00 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-audin-set-error-when-audio_format_read-fail.patch b/channels-audin-set-error-when-audio_format_read-fail.patch deleted file mode 100644 index 2f3b923..0000000 --- a/channels-audin-set-error-when-audio_format_read-fail.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 668352a2e241ba017679c11a22ecbe29d0b17401 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/channels-drdynvc-check-pointer-before-reset.patch b/channels-drdynvc-check-pointer-before-reset.patch deleted file mode 100644 index 2f45333..0000000 --- a/channels-drdynvc-check-pointer-before-reset.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 54ab7e13650f3ef9d912e9d0e336b9d7f22537ca Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/channels-drdynvc-reset-channel_callback-before-close.patch b/channels-drdynvc-reset-channel_callback-before-close.patch deleted file mode 100644 index 99c64b4..0000000 --- a/channels-drdynvc-reset-channel_callback-before-close.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 429260893d7f67011d916394974ec0294ff65a90 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/channels-drive-fix-constant-type.patch b/channels-drive-fix-constant-type.patch deleted file mode 100644 index 9bf0c8a..0000000 --- a/channels-drive-fix-constant-type.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3da319570c8a6be0a79b3306f1ed354c4a943259 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-rdpear-add-checks-for-itemSize.patch b/channels-rdpear-add-checks-for-itemSize.patch deleted file mode 100644 index 1d176c0..0000000 --- a/channels-rdpear-add-checks-for-itemSize.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 19f48dc7d615984a24a9be89f50ef9eb8f9bdb6a Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Mon, 12 Jan 2026 15:02:53 +0100 -Subject: [PATCH] [channels,rdpear] add checks for itemSize - -when a ndr read function is called with invalid arguments abort early. ---- - channels/rdpear/common/ndr.c | 22 ++++++++++++++++++---- - 1 file changed, 18 insertions(+), 4 deletions(-) - -diff --git a/channels/rdpear/common/ndr.c b/channels/rdpear/common/ndr.c -index d0bd6d959..ddb15a340 100644 ---- a/channels/rdpear/common/ndr.c -+++ b/channels/rdpear/common/ndr.c -@@ -518,6 +518,9 @@ BOOL ndr_read_uconformant_varying_array(NdrContext* context, wStream* s, - WINPR_ASSERT(itemType); - WINPR_ASSERT(ptarget); - -+ if (itemType->itemSize == 0) -+ return FALSE; -+ - UINT32 maxCount = 0; - UINT32 offset = 0; - UINT32 length = 0; -@@ -526,10 +529,10 @@ BOOL ndr_read_uconformant_varying_array(NdrContext* context, wStream* s, - !ndr_read_uint32(context, s, &length)) - return FALSE; - -- if ((length * itemType->itemSize) < hints->length) -+ if ((1ull * length * itemType->itemSize) > hints->length) - return FALSE; - -- if ((maxCount * itemType->itemSize) < hints->maxLength) -+ if ((1ull * maxCount * itemType->itemSize) > hints->maxLength) - return FALSE; - - BYTE* target = (BYTE*)ptarget; -@@ -552,6 +555,9 @@ BOOL ndr_write_uconformant_varying_array(NdrContext* context, wStream* s, - WINPR_ASSERT(itemType); - WINPR_ASSERT(psrc); - -+ if (itemType->itemSize == 0) -+ return FALSE; -+ - if (!ndr_write_uint32(context, s, hints->maxLength) || !ndr_write_uint32(context, s, 0) || - !ndr_write_uint32(context, s, hints->length)) - return FALSE; -@@ -581,8 +587,16 @@ BOOL ndr_read_uconformant_array(NdrContext* context, wStream* s, const NdrArrayH - if (!ndr_read_uint32(context, s, &count)) - return FALSE; - -- if ((count * itemType->itemSize < hints->count)) -- return FALSE; -+ if (itemType->arity == NDR_ARITY_SIMPLE) -+ { -+ if (count > hints->count) -+ return FALSE; -+ } -+ else -+ { -+ if ((1ull * count * itemType->itemSize) > hints->count) -+ return FALSE; -+ } - - BYTE* target = (BYTE*)vtarget; - for (UINT32 i = 0; i < count; i++, target += itemType->itemSize) --- -2.52.0 - diff --git a/channels-rdpecam-ensure-all-streams-are-stopped.patch b/channels-rdpecam-ensure-all-streams-are-stopped.patch deleted file mode 100644 index cf6cdbb..0000000 --- a/channels-rdpecam-ensure-all-streams-are-stopped.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f3ab1a16139036179d9852745fdade18fec11600 Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Mon, 26 Jan 2026 10:54:33 +0100 -Subject: [PATCH] [channels,rdpecam] ensure all streams are stopped - -When closing the channel ensure there are no more streams running. ---- - channels/rdpecam/client/camera_device_main.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/channels/rdpecam/client/camera_device_main.c b/channels/rdpecam/client/camera_device_main.c -index b76a37ca8..9ba3c65c5 100644 ---- a/channels/rdpecam/client/camera_device_main.c -+++ b/channels/rdpecam/client/camera_device_main.c -@@ -789,6 +789,9 @@ static UINT ecam_dev_on_close(IWTSVirtualChannelCallback* pChannelCallback) - - WLog_DBG(TAG, "entered"); - -+ for (size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++) -+ ecam_dev_stop_stream(dev, i); -+ - /* make sure this channel is not used for sample responses */ - for (size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++) - if (dev->streams[i].hSampleReqChannel == hchannel) --- -2.52.0 - diff --git a/channels-rdpsnd-terminate-thread-before-free.patch b/channels-rdpsnd-terminate-thread-before-free.patch deleted file mode 100644 index 6167956..0000000 --- a/channels-rdpsnd-terminate-thread-before-free.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 622bb7b4402491ca003f47472d0e478132673696 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-serial-explicitly-lock-serial-IrpThreads.patch b/channels-serial-explicitly-lock-serial-IrpThreads.patch deleted file mode 100644 index 1ed5b29..0000000 --- a/channels-serial-explicitly-lock-serial-IrpThreads.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 675c20f08f32ca5ec06297108bdf30147d6e2cd9 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-serial-lock-list-dictionary.patch b/channels-serial-lock-list-dictionary.patch deleted file mode 100644 index 189fe7f..0000000 --- a/channels-serial-lock-list-dictionary.patch +++ /dev/null @@ -1,87 +0,0 @@ -From b35aa3614d32bff3fc1272cd7c4617f711fca1a4 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-urbdrc-cancel-all-usb-transfers-on-channel-.patch b/channels-urbdrc-cancel-all-usb-transfers-on-channel-.patch deleted file mode 100644 index 0fccb7d..0000000 --- a/channels-urbdrc-cancel-all-usb-transfers-on-channel-.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 414f701464929c217f2509bcbd6d2c1f00f7ed73 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-urbdrc-check-interface-indices-before-use.patch b/channels-urbdrc-check-interface-indices-before-use.patch deleted file mode 100644 index 022ed0d..0000000 --- a/channels-urbdrc-check-interface-indices-before-use.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 7b7e6de8fe427a2f01d331056774aec69710590b Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Sat, 10 Jan 2026 08:43:40 +0100 -Subject: [PATCH] [channels,urbdrc] check interface indices before use - ---- - channels/urbdrc/client/data_transfer.c | 6 +- - .../urbdrc/client/libusb/libusb_udevice.c | 78 ++++++++++++------- - channels/urbdrc/common/msusb.c | 6 +- - 3 files changed, 54 insertions(+), 36 deletions(-) - -diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c -index e2270e565..762fe0d31 100644 ---- a/channels/urbdrc/client/data_transfer.c -+++ b/channels/urbdrc/client/data_transfer.c -@@ -454,14 +454,12 @@ static void func_select_all_interface_for_msconfig(IUDEVICE* pdev, - MSUSB_CONFIG_DESCRIPTOR* MsConfig) - { - MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces; -- BYTE InterfaceNumber = 0; -- BYTE AlternateSetting = 0; - UINT32 NumInterfaces = MsConfig->NumInterfaces; - - for (UINT32 inum = 0; inum < NumInterfaces; inum++) - { -- InterfaceNumber = MsInterfaces[inum]->InterfaceNumber; -- AlternateSetting = MsInterfaces[inum]->AlternateSetting; -+ const BYTE InterfaceNumber = MsInterfaces[inum]->InterfaceNumber; -+ const BYTE AlternateSetting = MsInterfaces[inum]->AlternateSetting; - pdev->select_interface(pdev, InterfaceNumber, AlternateSetting); - } - } -diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c -index afc7f11c6..aa5639f09 100644 ---- a/channels/urbdrc/client/libusb/libusb_udevice.c -+++ b/channels/urbdrc/client/libusb/libusb_udevice.c -@@ -582,25 +582,13 @@ static MSUSB_CONFIG_DESCRIPTOR* - libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsConfig) - { - UDEVICE* pdev = (UDEVICE*)idev; -- MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL; -- MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL; -- MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL; -- MSUSB_PIPE_DESCRIPTOR* MsPipe = NULL; -- MSUSB_PIPE_DESCRIPTOR** t_MsPipes = NULL; -- MSUSB_PIPE_DESCRIPTOR* t_MsPipe = NULL; -- LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig = NULL; -- const LIBUSB_INTERFACE* LibusbInterface = NULL; -- const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = NULL; -- const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint = NULL; -- BYTE LibusbNumEndpoint = 0; -- URBDRC_PLUGIN* urbdrc = NULL; - UINT32 MsOutSize = 0; - - if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc || !MsConfig) - return NULL; - -- urbdrc = pdev->urbdrc; -- LibusbConfig = pdev->LibusbConfig; -+ URBDRC_PLUGIN* urbdrc = pdev->urbdrc; -+ LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig = pdev->LibusbConfig; - - if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces) - { -@@ -608,28 +596,57 @@ libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsC - "Select Configuration: Libusb NumberInterfaces(%" PRIu8 ") is different " - "with MsConfig NumberInterfaces(%" PRIu32 ")", - LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces); -+ return NULL; - } - - /* replace MsPipes for libusb */ -- MsInterfaces = MsConfig->MsInterfaces; -+ MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces; - - for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++) - { -- MsInterface = MsInterfaces[inum]; -+ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum]; -+ if (MsInterface->InterfaceNumber >= MsConfig->NumInterfaces) -+ { -+ WLog_Print(urbdrc->log, WLOG_ERROR, -+ "MSUSB_CONFIG_DESCRIPTOR::NumInterfaces (%" PRIu32 -+ " <= MSUSB_INTERFACE_DESCRIPTOR::InterfaceNumber( %" PRIu8 ")", -+ MsConfig->NumInterfaces, MsInterface->InterfaceNumber); -+ return NULL; -+ } -+ -+ const LIBUSB_INTERFACE* LibusbInterface = -+ &LibusbConfig->interface[MsInterface->InterfaceNumber]; -+ if (MsInterface->AlternateSetting >= LibusbInterface->num_altsetting) -+ { -+ WLog_Print(urbdrc->log, WLOG_ERROR, -+ "LIBUSB_INTERFACE::num_altsetting (%" PRId32 -+ " <= MSUSB_INTERFACE_DESCRIPTOR::AlternateSetting( %" PRIu8 ")", -+ LibusbInterface->num_altsetting, MsInterface->AlternateSetting); -+ return NULL; -+ } -+ } -+ -+ for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++) -+ { -+ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum]; -+ - /* get libusb's number of endpoints */ -- LibusbInterface = &LibusbConfig->interface[MsInterface->InterfaceNumber]; -- LibusbAltsetting = &LibusbInterface->altsetting[MsInterface->AlternateSetting]; -- LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; -- t_MsPipes = -+ const LIBUSB_INTERFACE* LibusbInterface = -+ &LibusbConfig->interface[MsInterface->InterfaceNumber]; -+ const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = -+ &LibusbInterface->altsetting[MsInterface->AlternateSetting]; -+ const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; -+ MSUSB_PIPE_DESCRIPTOR** t_MsPipes = - (MSUSB_PIPE_DESCRIPTOR**)calloc(LibusbNumEndpoint, sizeof(MSUSB_PIPE_DESCRIPTOR*)); - - for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++) - { -- t_MsPipe = (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR)); -+ MSUSB_PIPE_DESCRIPTOR* t_MsPipe = -+ (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR)); - - if (pnum < MsInterface->NumberOfPipes && MsInterface->MsPipes) - { -- MsPipe = MsInterface->MsPipes[pnum]; -+ MSUSB_PIPE_DESCRIPTOR* MsPipe = MsInterface->MsPipes[pnum]; - t_MsPipe->MaximumPacketSize = MsPipe->MaximumPacketSize; - t_MsPipe->MaximumTransferSize = MsPipe->MaximumTransferSize; - t_MsPipe->PipeFlags = MsPipe->PipeFlags; -@@ -668,10 +685,12 @@ libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsC - for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++) - { - MsOutSize += 16; -- MsInterface = MsInterfaces[inum]; -+ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum]; - /* get libusb's interface */ -- LibusbInterface = &LibusbConfig->interface[MsInterface->InterfaceNumber]; -- LibusbAltsetting = &LibusbInterface->altsetting[MsInterface->AlternateSetting]; -+ const LIBUSB_INTERFACE* LibusbInterface = -+ &LibusbConfig->interface[MsInterface->InterfaceNumber]; -+ const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = -+ &LibusbInterface->altsetting[MsInterface->AlternateSetting]; - /* InterfaceHandle: 4 bytes - * --------------------------------------------------------------- - * ||<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>|| -@@ -688,15 +707,16 @@ libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsC - MsInterface->bInterfaceSubClass = LibusbAltsetting->bInterfaceSubClass; - MsInterface->bInterfaceProtocol = LibusbAltsetting->bInterfaceProtocol; - MsInterface->InitCompleted = 1; -- MsPipes = MsInterface->MsPipes; -- LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; -+ MSUSB_PIPE_DESCRIPTOR** MsPipes = MsInterface->MsPipes; -+ const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; - - for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++) - { - MsOutSize += 20; -- MsPipe = MsPipes[pnum]; -+ -+ MSUSB_PIPE_DESCRIPTOR* MsPipe = MsPipes[pnum]; - /* get libusb's endpoint */ -- LibusbEndpoint = &LibusbAltsetting->endpoint[pnum]; -+ const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint = &LibusbAltsetting->endpoint[pnum]; - /* PipeHandle: 4 bytes - * --------------------------------------------------------------- - * ||<<< 1 byte >>>|<<< 1 byte >>>|<<<<<<<<<< 2 byte >>>>>>>>>>>|| -diff --git a/channels/urbdrc/common/msusb.c b/channels/urbdrc/common/msusb.c -index 8d6809741..1b6e29aeb 100644 ---- a/channels/urbdrc/common/msusb.c -+++ b/channels/urbdrc/common/msusb.c -@@ -134,6 +134,8 @@ BOOL msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR* MsConfig, BYTE Interface - { - if (!MsConfig || !MsConfig->MsInterfaces) - return FALSE; -+ if (MsConfig->NumInterfaces <= InterfaceNumber) -+ return FALSE; - - msusb_msinterface_free(MsConfig->MsInterfaces[InterfaceNumber]); - MsConfig->MsInterfaces[InterfaceNumber] = NewMsInterface; -@@ -142,12 +144,10 @@ BOOL msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR* MsConfig, BYTE Interface - - MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_read(wStream* s) - { -- MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL; -- - if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 12)) - return NULL; - -- MsInterface = msusb_msinterface_new(); -+ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = msusb_msinterface_new(); - - if (!MsInterface) - return NULL; --- -2.52.0 - diff --git a/channels-urbdrc-do-not-free-MsConfig-on-failure.patch b/channels-urbdrc-do-not-free-MsConfig-on-failure.patch deleted file mode 100644 index 36c2985..0000000 --- a/channels-urbdrc-do-not-free-MsConfig-on-failure.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a304360d05cd2692ac4d87af017277d934863616 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-urbdrc-ensure-InterfaceNumber-is-within-ran.patch b/channels-urbdrc-ensure-InterfaceNumber-is-within-ran.patch deleted file mode 100644 index 70cf9dc..0000000 --- a/channels-urbdrc-ensure-InterfaceNumber-is-within-ran.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 2d563a50be17c1b407ca448b1321378c0726dd31 Mon Sep 17 00:00:00 2001 -From: akallabeth -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 - diff --git a/channels-video-fix-wrong-cast.patch b/channels-video-fix-wrong-cast.patch deleted file mode 100644 index 60585e1..0000000 --- a/channels-video-fix-wrong-cast.patch +++ /dev/null @@ -1,37 +0,0 @@ -From bd3c5d3ab73cbe10ac3c079fb0b26610d3231133 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/channels-video-unify-error-handling.patch b/channels-video-unify-error-handling.patch deleted file mode 100644 index 5b7a356..0000000 --- a/channels-video-unify-error-handling.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 0328bb3828b836d53b904187b0b6d49f940d1180 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/client-x11-fix-double-free-in-case-of-invalid-pointe.patch b/client-x11-fix-double-free-in-case-of-invalid-pointe.patch deleted file mode 100644 index 5a12e67..0000000 --- a/client-x11-fix-double-free-in-case-of-invalid-pointe.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0421b53fcb4a80c95f51342e4a2c40c68a4101d3 Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Mon, 19 Jan 2026 08:52:51 +0100 -Subject: [PATCH] [client,x11] fix double free in case of invalid pointer - ---- - client/X11/xf_graphics.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c -index df95a22b5..9d432c98b 100644 ---- a/client/X11/xf_graphics.c -+++ b/client/X11/xf_graphics.c -@@ -289,7 +289,6 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) - - #ifdef WITH_XCURSOR - UINT32 CursorFormat = 0; -- size_t size = 0; - xfContext* xfc = (xfContext*)context; - xfPointer* xpointer = (xfPointer*)pointer; - -@@ -304,19 +303,18 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) - xpointer->nCursors = 0; - xpointer->mCursors = 0; - -- size = 1ull * pointer->height * pointer->width * FreeRDPGetBytesPerPixel(CursorFormat); -+ const size_t size = -+ 1ull * pointer->height * pointer->width * FreeRDPGetBytesPerPixel(CursorFormat); - -- if (!(xpointer->cursorPixels = (XcursorPixel*)winpr_aligned_malloc(size, 16))) -+ xpointer->cursorPixels = (XcursorPixel*)winpr_aligned_malloc(size, 16); -+ if (!xpointer->cursorPixels) - goto fail; - - if (!freerdp_image_copy_from_pointer_data( - (BYTE*)xpointer->cursorPixels, CursorFormat, 0, 0, 0, pointer->width, pointer->height, - pointer->xorMaskData, pointer->lengthXorMask, pointer->andMaskData, - pointer->lengthAndMask, pointer->xorBpp, &context->gdi->palette)) -- { -- winpr_aligned_free(xpointer->cursorPixels); - goto fail; -- } - - #endif - --- -2.52.0 - diff --git a/codec-clear-check-clear_decomress-glyphData.patch b/codec-clear-check-clear_decomress-glyphData.patch deleted file mode 100644 index 2a9be7c..0000000 --- a/codec-clear-check-clear_decomress-glyphData.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 4498861d2b180cae552b5e2daedebe14312c2141 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Mon, 26 Jan 2026 16:32:13 +0100 -Subject: [PATCH] [codec,clear] check clear_decomress glyphData - -Backport of commit 243ecf804bb122e8e643a5c142ad5a49d7aa19ee. - -Co-Authored-By: Claude ---- - libfreerdp/codec/clear.c | 52 ++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 50 insertions(+), 2 deletions(-) - -diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c -index 603863c36..ca821f575 100644 ---- a/libfreerdp/codec/clear.c -+++ b/libfreerdp/codec/clear.c -@@ -1139,8 +1139,56 @@ INT32 clear_decompress(CLEAR_CONTEXT* WINPR_RESTRICT clear, const BYTE* WINPR_RE - - if (glyphData) - { -- if (!freerdp_image_copy_no_overlap(glyphData, clear->format, 0, 0, 0, nWidth, nHeight, -- pDstData, DstFormat, nDstStep, nXDst, nYDst, palette, -+ uint32_t w = MIN(nWidth, nDstWidth); -+ if (nXDst > nDstWidth) -+ { -+ WLog_WARN(TAG, "glyphData copy area x exceeds destination: x=%" PRIu32 " > %" PRIu32, -+ nXDst, nDstWidth); -+ w = 0; -+ } -+ else if (nXDst + w > nDstWidth) -+ { -+ WLog_WARN(TAG, -+ "glyphData copy area x + width exceeds destination: x=%" PRIu32 " + %" PRIu32 -+ " > %" PRIu32, -+ nXDst, w, nDstWidth); -+ w = nDstWidth - nXDst; -+ } -+ -+ if (w != nWidth) -+ { -+ WLog_WARN(TAG, -+ "glyphData copy area width truncated: requested=%" PRIu32 -+ ", truncated to %" PRIu32, -+ nWidth, w); -+ } -+ -+ uint32_t h = MIN(nHeight, nDstHeight); -+ if (nYDst > nDstHeight) -+ { -+ WLog_WARN(TAG, "glyphData copy area y exceeds destination: y=%" PRIu32 " > %" PRIu32, -+ nYDst, nDstHeight); -+ h = 0; -+ } -+ else if (nYDst + h > nDstHeight) -+ { -+ WLog_WARN(TAG, -+ "glyphData copy area y + height exceeds destination: x=%" PRIu32 " + %" PRIu32 -+ " > %" PRIu32, -+ nYDst, h, nDstHeight); -+ h = nDstHeight - nYDst; -+ } -+ -+ if (h != nHeight) -+ { -+ WLog_WARN(TAG, -+ "glyphData copy area height truncated: requested=%" PRIu32 -+ ", truncated to %" PRIu32, -+ nHeight, h); -+ } -+ -+ if (!freerdp_image_copy_no_overlap(glyphData, clear->format, 0, 0, 0, w, h, pDstData, -+ DstFormat, nDstStep, nXDst, nYDst, palette, - FREERDP_KEEP_DST_ALPHA)) - goto fail; - } --- -2.52.0 - diff --git a/codec-clear-fix-clear_resize_buffer-checks.patch b/codec-clear-fix-clear_resize_buffer-checks.patch deleted file mode 100644 index 9d32e9e..0000000 --- a/codec-clear-fix-clear_resize_buffer-checks.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 94235a5297db9cb83c2c23ade8a69cabe3e5f9f4 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 27 Jan 2026 16:15:28 +0100 -Subject: [PATCH] [codec,clear] fix clear_resize_buffer checks - -Backport of commit c4391827d7facfc874ca7f61a92afb82232a5748. - -Co-Authored-By: Claude ---- - libfreerdp/codec/clear.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c -index b0813937d..28450b357 100644 ---- a/libfreerdp/codec/clear.c -+++ b/libfreerdp/codec/clear.c -@@ -58,7 +58,7 @@ struct S_CLEAR_CONTEXT - NSC_CONTEXT* nsc; - UINT32 seqNumber; - BYTE* TempBuffer; -- UINT32 TempSize; -+ size_t TempSize; - UINT32 nTempStep; - UINT32 TempFormat; - UINT32 format; -@@ -328,25 +328,26 @@ static BOOL clear_decompress_subcode_rlex(wStream* WINPR_RESTRICT s, UINT32 bitm - - static BOOL clear_resize_buffer(CLEAR_CONTEXT* WINPR_RESTRICT clear, UINT32 width, UINT32 height) - { -- UINT32 size = 0; -- - if (!clear) - return FALSE; - -- size = ((width + 16) * (height + 16) * FreeRDPGetBytesPerPixel(clear->format)); -+ const UINT64 size = 1ull * (width + 16ull) * (height + 16ull); -+ const size_t bpp = FreeRDPGetBytesPerPixel(clear->format); -+ if (size > UINT32_MAX / bpp) -+ return FALSE; - -- if (size > clear->TempSize) -+ if (size > clear->TempSize / bpp) - { -- BYTE* tmp = (BYTE*)winpr_aligned_recalloc(clear->TempBuffer, size, sizeof(BYTE), 32); -+ BYTE* tmp = (BYTE*)winpr_aligned_recalloc(clear->TempBuffer, size, bpp, 32); - - if (!tmp) - { -- WLog_ERR(TAG, "clear->TempBuffer winpr_aligned_recalloc failed for %" PRIu32 " bytes", -+ WLog_ERR(TAG, "clear->TempBuffer winpr_aligned_recalloc failed for %" PRIu64 " bytes", - size); - return FALSE; - } - -- clear->TempSize = size; -+ clear->TempSize = size * bpp; - clear->TempBuffer = tmp; - } - --- -2.52.0 - diff --git a/codec-clear-fix-destination-checks.patch b/codec-clear-fix-destination-checks.patch deleted file mode 100644 index d07e883..0000000 --- a/codec-clear-fix-destination-checks.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6fe494ec5b0baf2fa604f5ae6a6237eb5dc0b66a Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Mon, 9 Mar 2026 13:55:01 +0100 -Subject: [PATCH] [codec,clear] fix destination checks - -Backport of commit 7d8fdce2d0ef337cb86cb37fc0c436c905e04d77. - -Made-with: Cursor ---- - libfreerdp/codec/clear.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c -index 2a4f894ea..4c42bb2bf 100644 ---- a/libfreerdp/codec/clear.c -+++ b/libfreerdp/codec/clear.c -@@ -490,16 +490,16 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* WINPR_RESTRICT clear, - nXDstRel = nXDst + xStart; - nYDstRel = nYDst + yStart; - -- if (1ull * xStart + width > nWidth) -+ if (1ull * nXDstRel + width > nDstWidth) - { -- WLog_ERR(TAG, "xStart %" PRIu16 " + width %" PRIu16 " > nWidth %" PRIu32 "", xStart, -- width, nWidth); -+ WLog_ERR(TAG, "nXDstRel %" PRIu32 " + width %" PRIu16 " > nDstWidth %" PRIu32 "", -+ nXDstRel, width, nDstWidth); - return FALSE; - } -- if (1ull * yStart + height > nHeight) -+ if (1ull * nYDstRel + height > nDstHeight) - { -- WLog_ERR(TAG, "yStart %" PRIu16 " + height %" PRIu16 " > nHeight %" PRIu32 "", yStart, -- height, nHeight); -+ WLog_ERR(TAG, "nYDstRel %" PRIu32 " + height %" PRIu16 " > nDstHeight %" PRIu32 "", -+ nYDstRel, height, nDstHeight); - return FALSE; - } - --- -2.53.0 - diff --git a/codec-clear-fix-off-by-one-length-check.patch b/codec-clear-fix-off-by-one-length-check.patch deleted file mode 100644 index 36b4d51..0000000 --- a/codec-clear-fix-off-by-one-length-check.patch +++ /dev/null @@ -1,31 +0,0 @@ -From f8688b57f6cfad9a0b05475a6afbde355ffab720 Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Thu, 15 Jan 2026 12:19:53 +0100 -Subject: [PATCH] [codec,clear] fix off by one length check - ---- - libfreerdp/codec/clear.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c -index 4a67a8ed6..0efa89f8d 100644 ---- a/libfreerdp/codec/clear.c -+++ b/libfreerdp/codec/clear.c -@@ -876,12 +876,12 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* WINPR_RESTRICT clear, - if (count > nHeight) - count = nHeight; - -- if (nXDstRel + i > nDstWidth) -+ if (nXDstRel + i >= nDstWidth) - return FALSE; - - for (UINT32 y = 0; y < count; y++) - { -- if (nYDstRel + y > nDstHeight) -+ if (nYDstRel + y >= nDstHeight) - return FALSE; - - BYTE* pDstPixel8 = --- -2.52.0 - diff --git a/codec-color-add-freerdp_glyph_convert_ex.patch b/codec-color-add-freerdp_glyph_convert_ex.patch deleted file mode 100644 index 0161bbf..0000000 --- a/codec-color-add-freerdp_glyph_convert_ex.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 1ea1d83a365f81628a2c38e9ec0223de6b975889 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - -+#include - #include - - #include -@@ -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 - diff --git a/codec-nsc-fix-use-of-nsc_process_message.patch b/codec-nsc-fix-use-of-nsc_process_message.patch deleted file mode 100644 index 3b04c94..0000000 --- a/codec-nsc-fix-use-of-nsc_process_message.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 7702ec2f2aadb0cfae86b00c177647e31f6159d4 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/codec-nsc-limit-copy-area-in-nsc_process_message.patch b/codec-nsc-limit-copy-area-in-nsc_process_message.patch deleted file mode 100644 index 3903855..0000000 --- a/codec-nsc-limit-copy-area-in-nsc_process_message.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 33e12b7cfb83875479822769ffd4fda799f294ff Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - -+#include - #include - #include - #include -@@ -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 - diff --git a/codec-planar-fix-decoder-length-checks.patch b/codec-planar-fix-decoder-length-checks.patch deleted file mode 100644 index a8a9fee..0000000 --- a/codec-planar-fix-decoder-length-checks.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 1bab198a2edd0d0e6e1627d21a433151ea190500 Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Thu, 15 Jan 2026 12:02:02 +0100 -Subject: [PATCH] [codec,planar] fix decoder length checks - ---- - libfreerdp/codec/planar.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c -index 1a06e36ed..94a640a55 100644 ---- a/libfreerdp/codec/planar.c -+++ b/libfreerdp/codec/planar.c -@@ -727,6 +727,11 @@ BOOL freerdp_bitmap_decompress_planar(BITMAP_PLANAR_CONTEXT* WINPR_RESTRICT plan - WINPR_ASSERT(planar); - WINPR_ASSERT(prims); - -+ if (planar->maxWidth < nSrcWidth) -+ return FALSE; -+ if (planar->maxHeight < nSrcHeight) -+ return FALSE; -+ - if (nDstStep <= 0) - nDstStep = nDstWidth * FreeRDPGetBytesPerPixel(DstFormat); - --- -2.52.0 - diff --git a/codec-planar-fix-missing-destination-bounds-checks.patch b/codec-planar-fix-missing-destination-bounds-checks.patch deleted file mode 100644 index 8ee655f..0000000 --- a/codec-planar-fix-missing-destination-bounds-checks.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 867763b853ea3efdffb3bba0b182890bef994974 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Mon, 9 Mar 2026 12:50:26 +0100 -Subject: [PATCH] [codec,planar] fix missing destination bounds checks - -Backport of commit a0be5cb87d760bb1c803ad1bb835aa1e73e62abc. - -Made-with: Cursor ---- - libfreerdp/codec/planar.c | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - -diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c -index 5df607051..58efbc627 100644 ---- a/libfreerdp/codec/planar.c -+++ b/libfreerdp/codec/planar.c -@@ -727,8 +727,9 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* WINPR_RESTRICT planar, - if (planar->maxHeight < nSrcHeight) - return FALSE; - -+ const UINT32 bpp = FreeRDPGetBytesPerPixel(DstFormat); - if (nDstStep <= 0) -- nDstStep = nDstWidth * FreeRDPGetBytesPerPixel(DstFormat); -+ nDstStep = nDstWidth * bpp; - - srcp = pSrcData; - -@@ -948,6 +949,24 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* WINPR_RESTRICT planar, - } - else /* RLE */ - { -+ if (nYDst + nSrcHeight > nTotalHeight) -+ { -+ WLog_ERR(TAG, -+ "planar plane destination Y %" PRIu32 " + height %" PRIu32 -+ " exceeds totalHeight %" PRIu32, -+ nYDst, nSrcHeight, nTotalHeight); -+ return FALSE; -+ } -+ -+ if ((nXDst + nSrcWidth) * bpp > nDstStep) -+ { -+ WLog_ERR(TAG, -+ "planar plane destination (X %" PRIu32 " + width %" PRIu32 -+ ") * bpp %" PRIu32 " exceeds stride %" PRIu32, -+ nXDst, nSrcWidth, bpp, nDstStep); -+ return FALSE; -+ } -+ - status = - planar_decompress_plane_rle(planes[0], rleSizes[0], pTempData, nTempStep, nXDst, - nYDst, nSrcWidth, nSrcHeight, 2, vFlip); /* RedPlane */ --- -2.53.0 - diff --git a/core-connection-print-SSL-warnings-after-init.patch b/core-connection-print-SSL-warnings-after-init.patch deleted file mode 100644 index f1368dd..0000000 --- a/core-connection-print-SSL-warnings-after-init.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 60ed73552ffdb499dddf06c119be9437da7f9261 Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Sun, 29 Dec 2024 10:22:56 +0100 -Subject: [PATCH] [core,connection] print SSL warnings after init - ---- - libfreerdp/core/connection.c | 1 + - libfreerdp/core/freerdp.c | 1 - - 2 files changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c -index 979ccdf60..001b56944 100644 ---- a/libfreerdp/core/connection.c -+++ b/libfreerdp/core/connection.c -@@ -319,6 +319,7 @@ BOOL rdp_client_connect(rdpRdp* rdp) - flags |= WINPR_SSL_INIT_ENABLE_FIPS; - - winpr_InitializeSSL(flags); -+ rdp_log_build_warnings(rdp); - - /* FIPS Mode forces the following and overrides the following(by happening later */ - /* in the command line processing): */ -diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c -index 94dad20a0..715da31d9 100644 ---- a/libfreerdp/core/freerdp.c -+++ b/libfreerdp/core/freerdp.c -@@ -802,7 +802,6 @@ BOOL freerdp_context_new_ex(freerdp* instance, rdpSettings* settings) - if (!rdp) - goto fail; - -- rdp_log_build_warnings(rdp); - context->rdp = rdp; - context->pubSub = rdp->pubSub; - --- -2.51.1 - diff --git a/core-info-fix-missing-NULL-check.patch b/core-info-fix-missing-NULL-check.patch deleted file mode 100644 index b96d9c6..0000000 --- a/core-info-fix-missing-NULL-check.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 51847b9d1c3a3720e4742d2a6ee92429f0c1af48 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/core-tcp-Don-t-ignore-connect-errors.patch b/core-tcp-Don-t-ignore-connect-errors.patch deleted file mode 100644 index b080e9b..0000000 --- a/core-tcp-Don-t-ignore-connect-errors.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 5a856bef31bdbecbaf69bd671d23add9779debd9 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 14 Jan 2026 11:37:16 +0100 -Subject: [PATCH] [core,tcp] Don't ignore connect errors - -Backport of commit 0bdd8da0993231216a7bb4d5e6e33e47d817a944. - -Co-Authored-By: Claude ---- - libfreerdp/core/tcp.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c -index 8e7ee20bd..6edfb6d71 100644 ---- a/libfreerdp/core/tcp.c -+++ b/libfreerdp/core/tcp.c -@@ -857,12 +857,19 @@ static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd, struct - if (WAIT_OBJECT_0 != status) - goto fail; - -- const SSIZE_T res = recv(sockfd, NULL, 0, 0); -- -- if (res == SOCKET_ERROR) - { -- if (WSAGetLastError() == WSAECONNRESET) -+ INT32 optval = 0; -+ socklen_t optlen = sizeof(optval); -+ if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0) -+ goto fail; -+ -+ if (optval != 0) -+ { -+ char ebuffer[256] = { 0 }; -+ WLog_DBG(TAG, "connect failed with error: %s [%" PRId32 "]", -+ winpr_strerror(optval, ebuffer, sizeof(ebuffer)), optval); - goto fail; -+ } - } - - status = WSAEventSelect(sockfd, handles[0], 0); --- -2.52.0 - diff --git a/core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch b/core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch deleted file mode 100644 index 8267f8d..0000000 --- a/core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 4864954a384e4028298e95a19795505f688b21ae Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 14 Jan 2026 11:38:11 +0100 -Subject: [PATCH] [core,tcp] Fix PreferIPv6OverIPv4 fallback to IPv4 addresses - -Backport of commit 0bdd8da0993231216a7bb4d5e6e33e47d817a944. - -Co-Authored-By: Claude ---- - libfreerdp/core/tcp.c | 61 ++++++++++++++++++++++++++++++++++++------- - 1 file changed, 51 insertions(+), 10 deletions(-) - -diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c -index 6edfb6d71..83cc9af1e 100644 ---- a/libfreerdp/core/tcp.c -+++ b/libfreerdp/core/tcp.c -@@ -1081,6 +1081,53 @@ int freerdp_tcp_connect(rdpContext* context, const char* hostname, int port, DWO - return transport_tcp_connect(context->rdp->transport, hostname, port, timeout); - } - -+static struct addrinfo* reorder_addrinfo_by_preference(rdpContext* context, struct addrinfo* addr) -+{ -+ WINPR_ASSERT(context); -+ WINPR_ASSERT(addr); -+ -+ const BOOL preferIPv6 = -+ freerdp_settings_get_bool(context->settings, FreeRDP_PreferIPv6OverIPv4); -+ if (!preferIPv6) -+ return addr; -+ -+ struct addrinfo* ipv6Head = NULL; -+ struct addrinfo* ipv6Tail = NULL; -+ struct addrinfo* otherHead = NULL; -+ struct addrinfo* otherTail = NULL; -+ -+ /* Partition the list into IPv6 and other addresses */ -+ while (addr) -+ { -+ struct addrinfo* next = addr->ai_next; -+ addr->ai_next = NULL; -+ -+ if (addr->ai_family == AF_INET6) -+ { -+ if (!ipv6Head) -+ ipv6Head = addr; -+ else -+ ipv6Tail->ai_next = addr; -+ ipv6Tail = addr; -+ } -+ else -+ { -+ if (!otherHead) -+ otherHead = addr; -+ else -+ otherTail->ai_next = addr; -+ otherTail = addr; -+ } -+ addr = next; -+ } -+ -+ /* Concatenate the lists */ -+ if (ipv6Tail) -+ ipv6Tail->ai_next = otherHead; -+ -+ return ipv6Head ? ipv6Head : otherHead; -+} -+ - static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct addrinfo** result, - UINT32 errorCode) - { -@@ -1091,14 +1138,6 @@ static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct - if (!addr) - goto fail; - -- if (freerdp_settings_get_bool(context->settings, FreeRDP_PreferIPv6OverIPv4)) -- { -- while (addr && (addr->ai_family != AF_INET6)) -- addr = addr->ai_next; -- if (!addr) -- addr = input; -- } -- - /* We want to force IPvX, abort if not detected */ - const UINT32 IPvX = freerdp_settings_get_uint32(context->settings, FreeRDP_ForceIPvX); - switch (IPvX) -@@ -1237,9 +1276,11 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons - - /* By default we take the first returned entry. - * -- * If PreferIPv6OverIPv4 = TRUE we force to IPv6 if there -- * is such an address available, but fall back to first if not found -+ * If PreferIPv6OverIPv4 = TRUE we reorder addresses by preference: -+ * IPv6 addresses come first, then other addresses. - */ -+ result = reorder_addrinfo_by_preference(context, result); -+ - const int rc = - get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND); - if (rc < 0) --- -2.52.0 - diff --git a/core-tcp-Try-next-DNS-entry-on-connect-failure.patch b/core-tcp-Try-next-DNS-entry-on-connect-failure.patch deleted file mode 100644 index c225276..0000000 --- a/core-tcp-Try-next-DNS-entry-on-connect-failure.patch +++ /dev/null @@ -1,76 +0,0 @@ -From e4adf227177fd807f47f8621a5e2568748619a23 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 14 Jan 2026 11:34:53 +0100 -Subject: [PATCH] [core,tcp] Try next DNS entry on connect failure - -Backport of commit bd67348eb3380a66b544835346191bd2138a5ba4. - -Co-Authored-By: Claude ---- - libfreerdp/core/tcp.c | 41 ++++++++++++++++++++++------------------- - 1 file changed, 22 insertions(+), 19 deletions(-) - -diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c -index 53e3a412f..8e7ee20bd 100644 ---- a/libfreerdp/core/tcp.c -+++ b/libfreerdp/core/tcp.c -@@ -1241,34 +1241,37 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons - do - { - sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); -+ if (sockfd >= 0) -+ { -+ if ((peerAddress = freerdp_tcp_address_to_string( -+ (const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL) -+ { -+ WLog_DBG(TAG, "connecting to peer %s", peerAddress); -+ free(peerAddress); -+ } -+ -+ if (!freerdp_tcp_connect_timeout(context, sockfd, addr->ai_addr, -+ addr->ai_addrlen, timeout)) -+ { -+ close(sockfd); -+ sockfd = -1; -+ } -+ } -+ - if (sockfd < 0) - { - const int lrc = get_next_addrinfo(context, addr->ai_next, &addr, - FREERDP_ERROR_CONNECT_FAILED); - if (lrc < 0) -+ { -+ freeaddrinfo(result); -+ freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED); -+ WLog_ERR(TAG, "failed to connect to %s", hostname); - return lrc; -+ } - } - } while (sockfd < 0); - -- if ((peerAddress = freerdp_tcp_address_to_string( -- (const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL) -- { -- WLog_DBG(TAG, "connecting to peer %s", peerAddress); -- free(peerAddress); -- } -- -- if (!freerdp_tcp_connect_timeout(context, sockfd, addr->ai_addr, addr->ai_addrlen, -- timeout)) -- { -- freeaddrinfo(result); -- close(sockfd); -- -- freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED); -- -- WLog_ERR(TAG, "failed to connect to %s", hostname); -- return -1; -- } -- - freeaddrinfo(result); - } - } --- -2.52.0 - diff --git a/core-tcp-fix-double-free-in-get_next_addrinfo.patch b/core-tcp-fix-double-free-in-get_next_addrinfo.patch deleted file mode 100644 index 04759ec..0000000 --- a/core-tcp-fix-double-free-in-get_next_addrinfo.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0a660bf3b3cf2660a4fa15bd37d8b8b3d03fbfef Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 14 Jan 2026 12:55:42 +0100 -Subject: [PATCH] [core,tcp] fix double free in get_next_addrinfo - -Backport of commit 48197426444b7b3587874b5eae175af1113beab8. - -Co-Authored-By: Claude ---- - libfreerdp/core/tcp.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c -index 83cc9af1e..a3e12d14b 100644 ---- a/libfreerdp/core/tcp.c -+++ b/libfreerdp/core/tcp.c -@@ -1164,7 +1164,7 @@ static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct - - fail: - freerdp_set_last_error_if_not(context, errorCode); -- freeaddrinfo(input); -+ *result = NULL; - return -1; - } - -@@ -1284,7 +1284,10 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons - const int rc = - get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND); - if (rc < 0) -+ { -+ freeaddrinfo(result); - return rc; -+ } - - do - { --- -2.52.0 - diff --git a/crypto-base64-ensure-char-is-singend.patch b/crypto-base64-ensure-char-is-singend.patch deleted file mode 100644 index 4f12e71..0000000 --- a/crypto-base64-ensure-char-is-singend.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 525e717db19b57cc498bb2e3f1d9d65383f16d3f Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 17 Feb 2026 14:54:30 +0100 -Subject: [PATCH] [crypto,base64] ensure char is singend - -Backport of commit 62a9e787edb2cfce9858fa4ceda5461680efc590. - -Co-Authored-By: Cursor ---- - libfreerdp/crypto/base64.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libfreerdp/crypto/base64.c b/libfreerdp/crypto/base64.c -index 315da9203..8d49d352e 100644 ---- a/libfreerdp/crypto/base64.c -+++ b/libfreerdp/crypto/base64.c -@@ -400,7 +400,8 @@ static INLINE char* base64_encode(const BYTE* WINPR_RESTRICT alphabet, - - static INLINE int base64_decode_char(const signed char* WINPR_RESTRICT alphabet, char c) - { -- if (c <= '\0') -+ /* ensure char is signed for this check */ -+ if ((int)c <= '\0') - return -1; - - return alphabet[(size_t)c]; --- -2.52.0 - diff --git a/freerdp.spec b/freerdp.spec index ae50314..b5f88cb 100644 --- a/freerdp.spec +++ b/freerdp.spec @@ -29,8 +29,8 @@ Name: freerdp Epoch: 2 -Version: 3.10.3 -Release: 12%{?dist} +Version: 3.24.2 +Release: 1%{?dist} Summary: Free implementation of the Remote Desktop Protocol (RDP) # The effective license is Apache-2.0 but: @@ -47,148 +47,6 @@ URL: http://www.freerdp.com/ Source0: FreeRDP-%{version}-repack.tar.gz Source1: freerdp_download_and_repack.sh -# https://bugzilla.redhat.com/show_bug.cgi?id=2365232 -Patch0: Initialize-function-pointers-after-resource-allocation.patch - -# https://issues.redhat.com/browse/RHEL-86251 -Patch1: Limit-threadpool-to-16-threads.patch -Patch2: Use-default-threadpool.patch -Patch3: Default-minimum-thread-count.patch -Patch4: Limit-minimum-threadpool-size.patch - -# https://issues.redhat.com/browse/RHEL-73724 -Patch: core-connection-print-SSL-warnings-after-init.patch - -# https://issues.redhat.com/browse/RHEL-140099 -Patch: core-tcp-Try-next-DNS-entry-on-connect-failure.patch -Patch: core-tcp-Don-t-ignore-connect-errors.patch -Patch: core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch -Patch: core-tcp-fix-double-free-in-get_next_addrinfo.patch - -# https://github.com/FreeRDP/FreeRDP/commit/c4a7c371342edf0d307cea728f56d3302f0ab38c -Patch: gdi-gfx-properly-clamp-SurfaceToSurface.patch - -# https://github.com/FreeRDP/FreeRDP/commit/c4391827d7facfc874ca7f61a92afb82232a5748 -Patch: codec-clear-fix-clear_resize_buffer-checks.patch - -# https://github.com/FreeRDP/FreeRDP/commit/f8688b57f6cfad9a0b05475a6afbde355ffab720 -Patch: codec-clear-fix-off-by-one-length-check.patch - -# https://github.com/FreeRDP/FreeRDP/commit/1bab198a2edd0d0e6e1627d21a433151ea190500 -Patch: codec-planar-fix-decoder-length-checks.patch - -# https://github.com/FreeRDP/FreeRDP/commit/243ecf804bb122e8e643a5c142ad5a49d7aa19ee -Patch: codec-clear-check-clear_decomress-glyphData.patch - -# https://github.com/FreeRDP/FreeRDP/commit/0421b53fcb4a80c95f51342e4a2c40c68a4101d3 -Patch: client-x11-fix-double-free-in-case-of-invalid-pointe.patch - -# https://github.com/FreeRDP/FreeRDP/commit/52106a26726a2aba77aa6d86014d2eb3507f0783 -Patch: cache-offscreen-invalidate-bitmap-before-free.patch - -# CVE-2026-22853 -# https://github.com/FreeRDP/FreeRDP/commit/19f48dc7d615984a24a9be89f50ef9eb8f9bdb6a -Patch: channels-rdpear-add-checks-for-itemSize.patch - -# CVE-2026-22855 -# https://github.com/FreeRDP/FreeRDP/commit/57c5647d98c2a026de8b681159cb188ca0439ef8 -Patch: utils-smartcard-add-length-validity-checks.patch - -# CVE-2026-22858 -# https://github.com/FreeRDP/FreeRDP/commit/62a9e787edb2cfce9858fa4ceda5461680efc590 -Patch: crypto-base64-ensure-char-is-singend.patch - -# CVE-2026-22859 -# https://github.com/FreeRDP/FreeRDP/commit/7b7e6de8fe427a2f01d331056774aec69710590b -Patch: channels-urbdrc-check-interface-indices-before-use.patch - -# CVE-2026-24678 -# https://github.com/FreeRDP/FreeRDP/commit/f3ab1a16139036179d9852745fdade18fec11600 -Patch: channels-rdpecam-ensure-all-streams-are-stopped.patch - -# CVE-2026-26955 -# https://github.com/FreeRDP/FreeRDP/commit/7d8fdce2d0ef337cb86cb37fc0c436c905e04d77 -Patch: codec-clear-fix-destination-checks.patch - -# CVE-2026-26965 -# 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 @@ -350,6 +208,7 @@ find . -name "*.c" -exec chmod 664 {} \; -DWITH_PCSC=ON \ -DWITH_PKCS11=ON \ -DWITH_PULSE=ON \ + -DWITH_RDTK=ON \ -DWITH_SAMPLE=OFF \ -DWITH_SERVER=%{?_with_server:ON}%{?!_with_server:OFF} \ -DWITH_SERVER_INTERFACE=%{?_with_server:ON}%{?!_with_server:OFF} \ @@ -512,6 +371,10 @@ find %{buildroot} -name "*.a" -delete %{_libdir}/pkgconfig/winpr-tools3.pc %changelog +* Thu Apr 09 2026 Ondrej Holy - 2:3.24.2-1 +- Update to 3.24.2 + Resolves: RHEL-80426 + * Tue Mar 31 2026 Ondrej Holy - 2:3.10.3-12 - Fix use of nsc_process_message - Increase timeout for TestSynchCritical diff --git a/gdi-gfx-properly-clamp-SurfaceToSurface.patch b/gdi-gfx-properly-clamp-SurfaceToSurface.patch deleted file mode 100644 index 8d51104..0000000 --- a/gdi-gfx-properly-clamp-SurfaceToSurface.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c4a7c371342edf0d307cea728f56d3302f0ab38c Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Thu, 15 Jan 2026 12:04:36 +0100 -Subject: [PATCH] [gdi,gfx] properly clamp SurfaceToSurface - ---- - libfreerdp/gdi/gfx.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c -index 56e6ff9ed..96ce10070 100644 ---- a/libfreerdp/gdi/gfx.c -+++ b/libfreerdp/gdi/gfx.c -@@ -1335,8 +1335,6 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, - { - UINT status = ERROR_INTERNAL_ERROR; - BOOL sameSurface = 0; -- UINT32 nWidth = 0; -- UINT32 nHeight = 0; - const RECTANGLE_16* rectSrc = NULL; - RECTANGLE_16 invalidRect; - gdiGfxSurface* surfaceSrc = NULL; -@@ -1362,8 +1360,8 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, - if (!is_rect_valid(rectSrc, surfaceSrc->width, surfaceSrc->height)) - goto fail; - -- nWidth = rectSrc->right - rectSrc->left; -- nHeight = rectSrc->bottom - rectSrc->top; -+ const UINT32 nWidth = rectSrc->right - rectSrc->left; -+ const UINT32 nHeight = rectSrc->bottom - rectSrc->top; - - for (UINT16 index = 0; index < surfaceToSurface->destPtsCount; index++) - { -@@ -1374,8 +1372,10 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, - if (!is_rect_valid(&rect, surfaceDst->width, surfaceDst->height)) - goto fail; - -+ const UINT32 rwidth = rect.right - rect.left; -+ const UINT32 rheight = rect.bottom - rect.top; - if (!freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline, -- destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, -+ destPt->x, destPt->y, rwidth, rheight, surfaceSrc->data, - surfaceSrc->format, surfaceSrc->scanline, rectSrc->left, - rectSrc->top, NULL, FREERDP_FLIP_NONE)) - goto fail; --- -2.52.0 - diff --git a/gdi-graphics-Use-freerdp_glyph_convert_ex.patch b/gdi-graphics-Use-freerdp_glyph_convert_ex.patch deleted file mode 100644 index da4572f..0000000 --- a/gdi-graphics-Use-freerdp_glyph_convert_ex.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e1bbcba2ee4ba8bb20bb73b16717a2e5d491825b Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -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 - diff --git a/sources b/sources index ffcfbf8..095051e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (FreeRDP-3.10.3-repack.tar.gz) = cd007c28267e4b9ace47487f7d44061b03b029409fa167209bb1273f3d1b79fdd3ed96c855d78ccb03bdbedf452009e3a1a21189d282faffdfc3b2b504d03574 +SHA512 (FreeRDP-3.24.2-repack.tar.gz) = e4fcd7ffede1db9541463ba3389fe412326f05b762d38a36a79361bfe0a0d5fa2f8a889988a0f1a7971277a6ee8e27669541f665568192b849ddd3544f24e72d diff --git a/utils-smartcard-add-length-validity-checks.patch b/utils-smartcard-add-length-validity-checks.patch deleted file mode 100644 index 55527c8..0000000 --- a/utils-smartcard-add-length-validity-checks.patch +++ /dev/null @@ -1,81 +0,0 @@ -From dc7bbfec41350c7cd3465d15f9facd8f9e2b0f20 Mon Sep 17 00:00:00 2001 -From: akallabeth -Date: Sun, 11 Jan 2026 09:03:57 +0100 -Subject: [PATCH] [utils,smartcard] add length validity checks - -Backport of commit 57c5647d98c2a026de8b681159cb188ca0439ef8. - -Co-Authored-By: Cursor ---- - libfreerdp/utils/smartcard_pack.c | 27 +++++++++++++++++++++------ - 1 file changed, 21 insertions(+), 6 deletions(-) - -diff --git a/libfreerdp/utils/smartcard_pack.c b/libfreerdp/utils/smartcard_pack.c -index 0ae0aff2c..52165def4 100644 ---- a/libfreerdp/utils/smartcard_pack.c -+++ b/libfreerdp/utils/smartcard_pack.c -@@ -97,8 +97,8 @@ static BOOL smartcard_ndr_pointer_read_(wStream* s, UINT32* index, UINT32* ptr, - return TRUE; - } - --static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t elementSize, -- ndr_ptr_t type) -+static LONG smartcard_ndr_read_ex(wStream* s, BYTE** data, size_t min, -+ size_t elementSize, ndr_ptr_t type, size_t* plen) - { - size_t len = 0; - size_t offset = 0; -@@ -107,6 +107,9 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t eleme - size_t required = 0; - - *data = NULL; -+ if (plen) -+ *plen = 0; -+ - switch (type) - { - case NDR_PTR_FULL: -@@ -181,11 +184,20 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t eleme - if (!r) - return SCARD_E_NO_MEMORY; - Stream_Read(s, r, len); -- smartcard_unpack_read_size_align(s, len, 4); -+ const LONG pad = smartcard_unpack_read_size_align(s, len, 4); -+ len += (size_t)pad; - *data = r; -+ if (plen) -+ *plen = len; - return STATUS_SUCCESS; - } - -+static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t elementSize, -+ ndr_ptr_t type) -+{ -+ return smartcard_ndr_read_ex(s, data, min, elementSize, type, NULL); -+} -+ - static BOOL smartcard_ndr_pointer_write(wStream* s, UINT32* index, DWORD length) - { - const UINT32 ndrPtr = 0x20000 + (*index) * 4; -@@ -3207,12 +3219,15 @@ LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call) - - if (ndrPtr) - { -- // TODO: call->cbAttrLen was larger than the pointer value. -- // TODO: Maybe need to refine the checks? -- status = smartcard_ndr_read(s, &call->pbAttr, 0, 1, NDR_PTR_SIMPLE); -+ size_t len = 0; -+ status = smartcard_ndr_read_ex(s, &call->pbAttr, 0, 1, NDR_PTR_SIMPLE, &len); - if (status != SCARD_S_SUCCESS) - return status; -+ if (call->cbAttrLen > len) -+ call->cbAttrLen = (DWORD)len; - } -+ else -+ call->cbAttrLen = 0; - smartcard_trace_set_attrib_call(call); - return SCARD_S_SUCCESS; - } --- -2.52.0 - diff --git a/winpr-synch-increase-timeout-for-TestSynchCritical.patch b/winpr-synch-increase-timeout-for-TestSynchCritical.patch deleted file mode 100644 index 64805f3..0000000 --- a/winpr-synch-increase-timeout-for-TestSynchCritical.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 907ca47e40583a7788674bb2f06258edd0c34223 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Dan=20Hor=C3=A1k?= -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 - #include - --#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 -