Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package freerdp2 for openSUSE:Factory 
checked in at 2026-02-24 15:39:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/freerdp2 (Old)
 and      /work/SRC/openSUSE:Factory/.freerdp2.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "freerdp2"

Tue Feb 24 15:39:38 2026 rev:8 rq:1334656 version:2.11.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/freerdp2/freerdp2.changes        2026-02-11 
18:50:14.000869209 +0100
+++ /work/SRC/openSUSE:Factory/.freerdp2.new.1977/freerdp2.changes      
2026-02-24 15:40:24.322907494 +0100
@@ -1,0 +2,14 @@
+Wed Feb 18 22:16:47 UTC 2026 - Michael Gorse <[email protected]>
+
+- Add more CVE fixes:
+  + freerdp-CVE-2026-24491.patch (CVE-2026-24491, bsc#1257981)
+  + freerdp-CVE-2026-24675.patch (CVE-2026-24675, bsc#1257982)
+  + freerdp-CVE-2026-24676.patch (CVE-2026-24676, bsc#1257983)
+  + freerdp-CVE-2026-24679.patch (CVE-2026-24679, bsc#1257986)
+  + freerdp-CVE-2026-24681.patch (CVE-2026-24681, bsc#1257988)
+  + freerdp-CVE-2026-24682.patch (CVE-2026-24682, bsc#1257989)
+  + freerdp-CVE-2026-24683.patch (CVE-2026-24683, bsc#1257990)
+  + freerdp-CVE-2026-24684.patch (CVE-2026-24684, bsc#1257991)
+  + freerdp-CVE-2026-24684-2.patch (CVE-2026-24684, bsc#1257991)
+
+-------------------------------------------------------------------

New:
----
  freerdp-CVE-2026-24491.patch
  freerdp-CVE-2026-24675.patch
  freerdp-CVE-2026-24676.patch
  freerdp-CVE-2026-24679.patch
  freerdp-CVE-2026-24681.patch
  freerdp-CVE-2026-24682.patch
  freerdp-CVE-2026-24683.patch
  freerdp-CVE-2026-24684-2.patch
  freerdp-CVE-2026-24684.patch

----------(New B)----------
  New:- Add more CVE fixes:
  + freerdp-CVE-2026-24491.patch (CVE-2026-24491, bsc#1257981)
  + freerdp-CVE-2026-24675.patch (CVE-2026-24675, bsc#1257982)
  New:  + freerdp-CVE-2026-24491.patch (CVE-2026-24491, bsc#1257981)
  + freerdp-CVE-2026-24675.patch (CVE-2026-24675, bsc#1257982)
  + freerdp-CVE-2026-24676.patch (CVE-2026-24676, bsc#1257983)
  New:  + freerdp-CVE-2026-24675.patch (CVE-2026-24675, bsc#1257982)
  + freerdp-CVE-2026-24676.patch (CVE-2026-24676, bsc#1257983)
  + freerdp-CVE-2026-24679.patch (CVE-2026-24679, bsc#1257986)
  New:  + freerdp-CVE-2026-24676.patch (CVE-2026-24676, bsc#1257983)
  + freerdp-CVE-2026-24679.patch (CVE-2026-24679, bsc#1257986)
  + freerdp-CVE-2026-24681.patch (CVE-2026-24681, bsc#1257988)
  New:  + freerdp-CVE-2026-24679.patch (CVE-2026-24679, bsc#1257986)
  + freerdp-CVE-2026-24681.patch (CVE-2026-24681, bsc#1257988)
  + freerdp-CVE-2026-24682.patch (CVE-2026-24682, bsc#1257989)
  New:  + freerdp-CVE-2026-24681.patch (CVE-2026-24681, bsc#1257988)
  + freerdp-CVE-2026-24682.patch (CVE-2026-24682, bsc#1257989)
  + freerdp-CVE-2026-24683.patch (CVE-2026-24683, bsc#1257990)
  New:  + freerdp-CVE-2026-24682.patch (CVE-2026-24682, bsc#1257989)
  + freerdp-CVE-2026-24683.patch (CVE-2026-24683, bsc#1257990)
  + freerdp-CVE-2026-24684.patch (CVE-2026-24684, bsc#1257991)
  New:  + freerdp-CVE-2026-24684.patch (CVE-2026-24684, bsc#1257991)
  + freerdp-CVE-2026-24684-2.patch (CVE-2026-24684, bsc#1257991)
  New:  + freerdp-CVE-2026-24683.patch (CVE-2026-24683, bsc#1257990)
  + freerdp-CVE-2026-24684.patch (CVE-2026-24684, bsc#1257991)
  + freerdp-CVE-2026-24684-2.patch (CVE-2026-24684, bsc#1257991)
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ freerdp2.spec ++++++
--- /var/tmp/diff_new_pack.j9twLV/_old  2026-02-24 15:40:25.254946188 +0100
+++ /var/tmp/diff_new_pack.j9twLV/_new  2026-02-24 15:40:25.254946188 +0100
@@ -74,6 +74,24 @@
 Patch20:        freerdp-CVE-2026-23532.patch
 # PATCH-FIX-UPSTREAM freerdp-CVE-2026-23534.patch bsc#1256944 [email protected] 
-- [codec,clear] fix off by one length check
 Patch22:        freerdp-CVE-2026-23534.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24491.patch bsc#1257981 [email protected] 
-- [channels,drdynvc] reset channel_callback before close
+Patch23:        freerdp-CVE-2026-24491.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24675.patch bsc#1257982 [email protected] 
-- [channels,urbdrc] do not free MsConfig on failure
+Patch24:        freerdp-CVE-2026-24675.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24676.patch bsc#1257983 [email protected] 
-- [channels,audin] reset audin->format
+Patch25:        freerdp-CVE-2026-24676.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24679.patch bsc#1257986 [email protected] 
-- [channels,urbdrc] ensure InterfaceNumber is within range
+Patch26:        freerdp-CVE-2026-24679.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24681.patch bsc#1257988 [email protected] 
-- [channels,urbdrc] cancel all usb transfers on channel close
+Patch27:        freerdp-CVE-2026-24681.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24682.patch bsc#1257989 [email protected] 
-- [channels,audin] fix audin_server_recv_formats cleanup
+Patch28:        freerdp-CVE-2026-24682.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24683.patch bsc#1257990 [email protected] 
-- [channels,ainput] lock context when updating listener
+Patch29:        freerdp-CVE-2026-24683.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24684.patch bsc#1257991 [email protected] 
-- [channels,rdpsnd] terminate thread before free
+Patch30:        freerdp-CVE-2026-24684.patch
+# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24684-2.patch bsc#1257991 
[email protected] -- [channel,rdpsnd] only clean up thread before free
+Patch31:        freerdp-CVE-2026-24684-2.patch
 BuildRequires:  cmake >= 2.8
 BuildRequires:  cups-devel
 BuildRequires:  ed

++++++ freerdp-CVE-2026-24491.patch ++++++
>From e02e052f6692550e539d10f99de9c35a23492db2 Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
Date: Mon, 26 Jan 2026 10:06:29 +0100
Subject: [PATCH] [channels,drdynvc] reset channel_callback before close

The channel_callback usually frees up the memory of the callback. To
ensure that there is no access to any of the data structures in it
invalidate the pointer used to access it before a free.
---
 channels/drdynvc/client/drdynvc_main.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff -rup freerdp-2.11.7.orig/channels/drdynvc/client/drdynvc_main.c 
freerdp-2.11.7/channels/drdynvc/client/drdynvc_main.c
--- freerdp-2.11.7.orig/channels/drdynvc/client/drdynvc_main.c  2024-04-22 
04:26:59.000000000 -0500
+++ freerdp-2.11.7/channels/drdynvc/client/drdynvc_main.c       2026-02-18 
13:43:43.788110262 -0600
@@ -346,10 +346,11 @@ static void dvcman_channel_free(void* ar
 
        if (channel)
        {
-               if (channel->channel_callback)
+               IWTSVirtualChannelCallback* cb = channel->channel_callback;
+               channel->channel_callback = NULL;
+               if (cb)
                {
-                       IFCALL(channel->channel_callback->OnClose, 
channel->channel_callback);
-                       channel->channel_callback = NULL;
+                       IFCALL(channel->channel_callback->OnClose, cb);
                }
 
                if (channel->status == CHANNEL_RC_OK)
@@ -573,7 +574,6 @@ static UINT dvcman_open_channel(drdynvcP
                                 UINT32 ChannelId)
 {
        DVCMAN_CHANNEL* channel;
-       IWTSVirtualChannelCallback* pCallback;
        UINT error;
        channel = (DVCMAN_CHANNEL*)dvcman_find_channel_by_id(pChannelMgr, 
ChannelId);
 
@@ -585,7 +585,7 @@ static UINT dvcman_open_channel(drdynvcP
 
        if (channel->status == CHANNEL_RC_OK)
        {
-               pCallback = channel->channel_callback;
+               IWTSVirtualChannelCallback* pCallback = 
channel->channel_callback;
 
                if (pCallback->OnOpen)
                {

++++++ freerdp-CVE-2026-24675.patch ++++++
>From d676518809c319eec15911c705c13536036af2ae Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
Date: Mon, 26 Jan 2026 11:54:56 +0100
Subject: [PATCH] [channels,urbdrc] do not free MsConfig on failure

let the channel handle it later.
---
 channels/urbdrc/client/data_transfer.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff -urp FreeRDP-3.10.3.orig/channels/urbdrc/client/data_transfer.c 
FreeRDP-3.10.3/channels/urbdrc/client/data_transfer.c
--- FreeRDP-3.10.3.orig/channels/urbdrc/client/data_transfer.c  2024-12-17 
03:06:36.000000000 -0600
+++ FreeRDP-3.10.3/channels/urbdrc/client/data_transfer.c       2026-02-17 
19:11:56.838805227 -0600
@@ -577,10 +577,8 @@ static UINT urb_select_interface(IUDEVIC
        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))
        {

++++++ freerdp-CVE-2026-24676.patch ++++++
>From 026b81ae5831ac1598d8f7371e0d0996fac7db00 Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
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


++++++ freerdp-CVE-2026-24679.patch ++++++
>From 2d563a50be17c1b407ca448b1321378c0726dd31 Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
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 -urp freerdp-2.11.7.orig/channels/urbdrc/client/libusb/libusb_udevice.c 
freerdp-2.11.7/channels/urbdrc/client/libusb/libusb_udevice.c
--- freerdp-2.11.7.orig/channels/urbdrc/client/libusb/libusb_udevice.c  
2026-02-18 14:18:47.541009536 -0600
+++ freerdp-2.11.7/channels/urbdrc/client/libusb/libusb_udevice.c       
2026-02-18 14:25:17.762339152 -0600
@@ -528,19 +528,19 @@ static int libusb_udev_select_interface(
 {
        int error = 0, diff = 0;
        UDEVICE* pdev = (UDEVICE*)idev;
-       URBDRC_PLUGIN* urbdrc;
-       MSUSB_CONFIG_DESCRIPTOR* MsConfig;
-       MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces;
 
        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,

++++++ freerdp-CVE-2026-24681.patch ++++++
>From 414f701464929c217f2509bcbd6d2c1f00f7ed73 Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
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


++++++ freerdp-CVE-2026-24682.patch ++++++
>From 1c5c74223179d425a1ce6dbbb6a3dd2a958b7aee Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
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(-)

Only in freerdp-2.11.7/channels/audin/client: audin_main.c.orig
diff -urp freerdp-2.11.7.orig/channels/audin/server/audin.c 
freerdp-2.11.7/channels/audin/server/audin.c
--- freerdp-2.11.7.orig/channels/audin/server/audin.c   2024-04-22 
04:26:59.000000000 -0500
+++ freerdp-2.11.7/channels/audin/server/audin.c        2026-02-18 
15:31:34.941700297 -0600
@@ -215,7 +215,7 @@ static UINT audin_server_recv_formats(au
 
                if (!audio_format_read(s, format))
                {
-                       audio_formats_free(audin->context.client_formats, i);
+                       audio_formats_free(audin->context.client_formats, 
audin->context.num_client_formats);
                        audin->context.client_formats = NULL;
                        WLog_ERR(TAG, "expected length at least 18, but got %" 
PRIu32 "", length);
                        return ERROR_INVALID_DATA;

++++++ freerdp-CVE-2026-24683.patch ++++++
>From d9ca272dce7a776ab475e9b1a8e8c3d2968c8486 Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
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 -urp freerdp-2.11.7.orig/channels/ainput/client/ainput_main.c 
freerdp-2.11.7/channels/ainput/client/ainput_main.c
--- freerdp-2.11.7.orig/channels/ainput/client/ainput_main.c    2024-04-22 
04:26:59.000000000 -0500
+++ freerdp-2.11.7/channels/ainput/client/ainput_main.c 2026-02-18 
16:06:17.371535339 -0600
@@ -69,6 +69,7 @@ struct AINPUT_PLUGIN_
        UINT32 MajorVersion;
        UINT32 MinorVersion;
        BOOL initialized;
+       CRITICAL_SECTION lock;
 };
 
 /**
@@ -109,10 +110,7 @@ static UINT ainput_on_data_received(IWTS
 
 static UINT ainput_send_input_event(AInputClientContext* context, UINT64 
flags, INT32 x, INT32 y)
 {
-       AINPUT_PLUGIN* ainput;
-       AINPUT_CHANNEL_CALLBACK* callback;
        BYTE buffer[32] = { 0 };
-       UINT64 time;
        wStream sbuffer = { 0 };
        wStream* s = &sbuffer;
 
@@ -121,8 +119,8 @@ static UINT ainput_send_input_event(AInp
        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);
        WINPR_ASSERT(ainput->listener_callback);
 
@@ -132,8 +130,6 @@ static UINT ainput_send_input_event(AInp
                          ainput->MajorVersion, ainput->MinorVersion);
                return CHANNEL_RC_UNSUPPORTED_VERSION;
        }
-       callback = ainput->listener_callback->channel_callback;
-       WINPR_ASSERT(callback);
 
        {
                char buffer[128] = { 0 };
@@ -152,10 +148,15 @@ static UINT ainput_send_input_event(AInp
        Stream_SealLength(s);
 
        /* ainput back what we have received. AINPUT does not have any message 
IDs. */
+       EnterCriticalSection(&ainput->lock);
+       AINPUT_CHANNEL_CALLBACK* 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;
 }
 
 /**
@@ -167,8 +168,16 @@ static UINT ainput_on_close(IWTSVirtualC
 {
        AINPUT_CHANNEL_CALLBACK* callback = 
(AINPUT_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;
 }
 
@@ -255,6 +264,8 @@ static UINT ainput_plugin_initialize(IWT
 static UINT ainput_plugin_terminated(IWTSPlugin* pPlugin)
 {
        AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)pPlugin;
+       WINPR_ASSERT(ainput);
+
        if (ainput && ainput->listener_callback)
        {
                IWTSVirtualChannelManager* mgr = 
ainput->listener_callback->channel_mgr;
@@ -266,6 +277,7 @@ static UINT ainput_plugin_terminated(IWT
                free(ainput->listener_callback);
                free(ainput->iface.pInterface);
        }
+       DeleteCriticalSection(&ainput->lock);
        free(ainput);
 
        return CHANNEL_RC_OK;
@@ -306,7 +318,11 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINT
 
                context->handle = (void*)ainput;
                context->AInputSendInputEvent = ainput_send_input_event;
+       InitializeCriticalSection(&ainput->lock);
+
+       EnterCriticalSection(&ainput->lock);
                ainput->iface.pInterface = (void*)context;
+       LeaveCriticalSection(&ainput->lock);
 
                status = pEntryPoints->RegisterPlugin(pEntryPoints, 
AINPUT_CHANNEL_NAME, &ainput->iface);
        }

++++++ freerdp-CVE-2026-24684-2.patch ++++++
>From afa6851dc80835d3101e40fcef51b6c5c0f43ea5 Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
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 -urp freerdp-2.11.7.orig/channels/rdpsnd/client/rdpsnd_main.c 
freerdp-2.11.7/channels/rdpsnd/client/rdpsnd_main.c
--- freerdp-2.11.7.orig/channels/rdpsnd/client/rdpsnd_main.c    2026-02-18 
17:09:35.837782540 -0600
+++ freerdp-2.11.7/channels/rdpsnd/client/rdpsnd_main.c 2026-02-18 
19:31:56.239148250 -0600
@@ -132,6 +132,8 @@ struct rdpsnd_plugin
        BOOL applyVolume;
 };
 
+static DWORD WINAPI play_thread(LPVOID arg);
+
 static const char* rdpsnd_is_dyn_str(BOOL dynamic)
 {
        if (dynamic)
@@ -1266,7 +1268,6 @@ static void cleanup_internals(rdpsndPlug
        if (!rdpsnd)
                return;
 
-       rdpsnd_terminate_thread(rdpsnd);
        if (rdpsnd->pool)
                StreamPool_Return(rdpsnd->pool, rdpsnd->data_in);
 
@@ -1330,6 +1331,7 @@ static void free_internals(rdpsndPlugin*
        if (!rdpsnd)
                return;
 
+       rdpsnd_terminate_thread(rdpsnd);
        freerdp_dsp_context_free(rdpsnd->dsp_context);
        StreamPool_Free(rdpsnd->pool);
        rdpsnd->pool = NULL;
@@ -1352,6 +1354,23 @@ static BOOL allocate_internals(rdpsndPlu
                        return FALSE;
        }
 
+       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;
+       }
+
        return TRUE;
 }
 
@@ -1390,23 +1409,9 @@ static DWORD WINAPI play_thread(LPVOID a
 
 static UINT rdpsnd_virtual_channel_event_initialized(rdpsndPlugin* rdpsnd)
 {
-       wObject obj = { 0 };
-
-       if (!rdpsnd)
-               return ERROR_INVALID_PARAMETER;
-
-       obj.fnObjectFree = _queue_free;
-       rdpsnd->queue = MessageQueue_New(&obj);
-       if (!rdpsnd->queue)
-               return CHANNEL_RC_NO_MEMORY;
-
        if (!allocate_internals(rdpsnd))
                return CHANNEL_RC_NO_MEMORY;
 
-       rdpsnd->thread = CreateThread(NULL, 0, play_thread, rdpsnd, 0, NULL);
-       if (!rdpsnd->thread)
-               return CHANNEL_RC_INITIALIZATION_ERROR;
-
        return CHANNEL_RC_OK;
 }
 
@@ -1414,8 +1419,6 @@ void rdpsnd_virtual_channel_event_termin
 {
        if (rdpsnd)
        {
-               rdpsnd_terminate_thread(rdpsnd);
-
                free_internals(rdpsnd);
                audio_formats_free(rdpsnd->fixed_format, 1);
                free(rdpsnd->subsystem);
@@ -1604,13 +1607,13 @@ static UINT rdpsnd_on_close(IWTSVirtualC
 
        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;
 }

++++++ freerdp-CVE-2026-24684.patch ++++++
>From 622bb7b4402491ca003f47472d0e478132673696 Mon Sep 17 00:00:00 2001
From: akallabeth <[email protected]>
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 -urp freerdp-2.11.7.orig/channels/rdpsnd/client/rdpsnd_main.c 
freerdp-2.11.7/channels/rdpsnd/client/rdpsnd_main.c
--- freerdp-2.11.7.orig/channels/rdpsnd/client/rdpsnd_main.c    2024-04-22 
04:26:59.000000000 -0500
+++ freerdp-2.11.7/channels/rdpsnd/client/rdpsnd_main.c 2026-02-18 
16:10:15.171328421 -0600
@@ -1244,11 +1244,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);
 
@@ -1396,14 +1414,7 @@ void rdpsnd_virtual_channel_event_termin
 {
        if (rdpsnd)
        {
-               if (rdpsnd->queue)
-                       MessageQueue_PostQuit(rdpsnd->queue, 0);
-               if (rdpsnd->thread)
-               {
-                       WaitForSingleObject(rdpsnd->thread, INFINITE);
-                       CloseHandle(rdpsnd->thread);
-               }
-               MessageQueue_Free(rdpsnd->queue);
+               rdpsnd_terminate_thread(rdpsnd);
 
                free_internals(rdpsnd);
                audio_formats_free(rdpsnd->fixed_format, 1);

Reply via email to