Sync factory for CVE fixes. #1

Manually merged
yfjiang merged 24 commits from yfjiang/freerdp2:leap-16.0 into leap-16.0 2026-03-04 18:40:51 +01:00
29 changed files with 1444 additions and 7 deletions

3
.gitattributes vendored
View File

@@ -1,4 +1,4 @@
## Default LFS
*.changes merge=merge-changes
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
@@ -12,6 +12,7 @@
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tar filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text

5
.gitignore vendored
View File

@@ -1 +1,4 @@
.osc
*.obscpio
*.osc
_build.*
.pbuild

View File

@@ -0,0 +1,143 @@
From 681a273cbba744b65e44d0205bce42f2ca794576 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Noel?= <sebastien@twolife.be>
Date: Tue, 30 Jul 2024 11:29:58 +0200
Subject: [PATCH] Fix build with ffmpeg 7
cherry picked from d0c5b1ae4289c7f3cde3fbc031cb4a3160df05ff
from freerdp3
---
libfreerdp/codec/dsp_ffmpeg.c | 28 ++++++++++------------------
1 file changed, 10 insertions(+), 18 deletions(-)
Index: freerdp-2.11.7/libfreerdp/codec/dsp_ffmpeg.c
===================================================================
--- freerdp-2.11.7.orig/libfreerdp/codec/dsp_ffmpeg.c
+++ freerdp-2.11.7/libfreerdp/codec/dsp_ffmpeg.c
@@ -225,18 +225,15 @@ static void ffmpeg_close_context(FREERDP
static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
{
int ret;
- int layout;
- const AUDIO_FORMAT* format;
if (!context || context->isOpen)
return FALSE;
- format = &context->format;
+ const AUDIO_FORMAT* format = &context->format;
if (!format)
return FALSE;
- layout = av_get_default_channel_layout(format->nChannels);
context->id = ffmpeg_get_avcodec(format);
if (ffmpeg_codec_is_filtered(context->id, context->encoder))
@@ -270,8 +267,7 @@ static BOOL ffmpeg_open_context(FREERDP_
break;
}
- context->context->channels = format->nChannels;
- context->context->channel_layout = layout;
+ av_channel_layout_default(&context->context->ch_layout, format->nChannels);
context->context->sample_rate = format->nSamplesPerSec;
context->context->block_align = format->nBlockAlign;
context->context->bit_rate = format->nAvgBytesPerSec * 8;
@@ -314,8 +310,7 @@ static BOOL ffmpeg_open_context(FREERDP_
if (!context->rcontext)
goto fail;
- context->frame->channel_layout = layout;
- context->frame->channels = format->nChannels;
+ av_channel_layout_default(&context->frame->ch_layout, format->nChannels);
context->frame->sample_rate = format->nSamplesPerSec;
context->frame->format = AV_SAMPLE_FMT_S16;
@@ -330,13 +325,11 @@ static BOOL ffmpeg_open_context(FREERDP_
context->resampled->sample_rate = format->nSamplesPerSec;
}
- context->resampled->channel_layout = layout;
- context->resampled->channels = format->nChannels;
+ av_channel_layout_default(&context->resampled->ch_layout, format->nChannels);
if (context->context->frame_size > 0)
{
- context->buffered->channel_layout = context->resampled->channel_layout;
- context->buffered->channels = context->resampled->channels;
+ av_channel_layout_copy(&context->buffered->ch_layout, &context->resampled->ch_layout);
context->buffered->format = context->resampled->format;
context->buffered->nb_samples = context->context->frame_size;
@@ -421,7 +414,7 @@ static BOOL ffmpeg_encode_frame(AVCodecC
if (in->format == AV_SAMPLE_FMT_FLTP)
{
uint8_t** pp = in->extended_data;
- for (int y = 0; y < in->channels; y++)
+ for (int y = 0; y < in->ch_layout.nb_channels; y++)
{
float* data = (float*)pp[y];
for (int x = 0; x < in->nb_samples; x++)
@@ -477,14 +470,13 @@ static BOOL ffmpeg_fill_frame(AVFrame* f
size_t size)
{
int ret, bpp;
- frame->channels = inputFormat->nChannels;
+ av_channel_layout_default(&frame->ch_layout, inputFormat->nChannels);
frame->sample_rate = inputFormat->nSamplesPerSec;
frame->format = ffmpeg_sample_format(inputFormat);
- frame->channel_layout = av_get_default_channel_layout(frame->channels);
bpp = av_get_bytes_per_sample(frame->format);
frame->nb_samples = size / inputFormat->nChannels / bpp;
- if ((ret = avcodec_fill_audio_frame(frame, frame->channels, frame->format, data, size, 1)) < 0)
+ if ((ret = avcodec_fill_audio_frame(frame, inputFormat->nChannels, frame->format, data, size, 1)) < 0)
{
const char* err = av_err2str(ret);
WLog_ERR(TAG, "Error during audio frame fill %s [%d]", err, ret);
@@ -566,7 +558,7 @@ static BOOL ffmpeg_decode(AVCodecContext
}
{
- const size_t data_size = resampled->channels * resampled->nb_samples * 2;
+ const size_t data_size = resampled->ch_layout.nb_channels * resampled->nb_samples * 2;
Stream_EnsureRemainingCapacity(out, data_size);
Stream_Write(out, resampled->data[0], data_size);
}
@@ -664,7 +656,7 @@ BOOL freerdp_dsp_ffmpeg_encode(FREERDP_D
rc =
av_samples_copy(context->buffered->extended_data, context->resampled->extended_data,
(int)context->bufferedSamples, copied, inSamples,
- context->context->channels, context->context->sample_fmt);
+ context->context->ch_layout.nb_channels, context->context->sample_fmt);
rest -= inSamples;
copied += inSamples;
context->bufferedSamples += (UINT32)inSamples;
Index: freerdp-2.11.7/libfreerdp/codec/h264_ffmpeg.c
===================================================================
--- freerdp-2.11.7.orig/libfreerdp/codec/h264_ffmpeg.c
+++ freerdp-2.11.7/libfreerdp/codec/h264_ffmpeg.c
@@ -100,10 +100,10 @@ static void libavcodec_destroy_encoder(H
if (sys->codecEncoderContext)
{
- avcodec_close(sys->codecEncoderContext);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100)
avcodec_free_context(&sys->codecEncoderContext);
#else
+ avcodec_close(sys->codecEncoderContext);
av_free(sys->codecEncoderContext);
#endif
}
@@ -430,10 +430,10 @@ static void libavcodec_uninit(H264_CONTE
if (sys->codecDecoderContext)
{
- avcodec_close(sys->codecDecoderContext);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100)
avcodec_free_context(&sys->codecDecoderContext);
#else
+ avcodec_close(sys->codecDecoderContext);
av_free(sys->codecDecoderContext);
#endif
}

View File

@@ -0,0 +1,32 @@
From: Alessandro Bono <alessandro.bono369@gmail.com>
Date: Wed, 8 May 2024 16:06:17 +0200
Subject: info: Fix incompatible pointer type
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
This fixes the following:
```
libfreerdp/core/info.c: In function rdp_read_info_null_string:
libfreerdp/core/info.c:88:39: error: initialization of const WCHAR * {aka const short unsigned int *} from incompatible pointer type BYTE * {aka unsigned char *} [-Wincompatible-pointer-types]
88 | const WCHAR* domain = Stream_Pointer(s);
```
(cherry picked from commit 4f411197dc9d2076f00748b1178a60b2423030bf)
---
libfreerdp/core/info.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
index 9aaa6cf..c9b2fc6 100644
--- a/libfreerdp/core/info.c
+++ b/libfreerdp/core/info.c
@@ -85,7 +85,7 @@ static BOOL rdp_read_info_null_string(const char* what, UINT32 flags, wStream* s
if (cbLen > 0)
{
- const WCHAR* domain = Stream_Pointer(s);
+ const WCHAR* domain = (WCHAR*)Stream_Pointer(s);
if (isNullTerminated && (max > 0))
max -= nullSize;

View File

@@ -0,0 +1,38 @@
From: Alessandro Bono <alessandro.bono369@gmail.com>
Date: Wed, 8 May 2024 16:06:26 +0200
Subject: redirection: Fix incompatible pointer type
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
This fixes the following:
```
libfreerdp/core/redirection.c: In function redirection_copy_data:
libfreerdp/core/redirection.c:91:31: error: passing argument 1 of redirection_free_data from incompatible pointer type [-Wincompatible-pointer-types]
91 | redirection_free_data(dst, plen);
| ^~~
| |
| char **
libfreerdp/core/redirection.c:80:42: note: expected BYTE ** {aka unsigned char **} but argument is of type char **
80 | static void redirection_free_data(BYTE** str, UINT32* length)
| ~~~~~~~^~~
```
(cherry picked from commit f3ed1f1ac367eb21f93c9fba5047447fdccdb5cc)
---
libfreerdp/core/redirection.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c
index 59c6dbc..63bc8cc 100644
--- a/libfreerdp/core/redirection.c
+++ b/libfreerdp/core/redirection.c
@@ -86,7 +86,7 @@ static void redirection_free_data(BYTE** str, UINT32* length)
*str = NULL;
}
-static BOOL redirection_copy_data(char** dst, UINT32* plen, const char* str, UINT32 len)
+static BOOL redirection_copy_data(BYTE** dst, UINT32* plen, const BYTE* str, UINT32 len)
{
redirection_free_data(dst, plen);

View File

@@ -0,0 +1,33 @@
From: Alessandro Bono <alessandro.bono369@gmail.com>
Date: Wed, 8 May 2024 16:06:30 +0200
Subject: redirection: Fix incompatible pointer type
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
This fixes the following:
```
libfreerdp/core/redirection.c: In function freerdp_settings_set_pointer_len:
libfreerdp/core/redirection.c:112:31: error: assignment to BYTE ** {aka unsigned char **} from incompatible pointer type char ** [-Wincompatible-pointer-types]
112 | pdata = &settings->TargetNetAddress;
| ^
```
(cherry picked from commit 7894a7dfc5f811cb5dacc57a09236c11744b1ec8)
---
libfreerdp/core/redirection.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c
index 63bc8cc..4872d4b 100644
--- a/libfreerdp/core/redirection.c
+++ b/libfreerdp/core/redirection.c
@@ -109,7 +109,7 @@ static BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, c
switch (id)
{
case FreeRDP_TargetNetAddress:
- pdata = &settings->TargetNetAddress;
+ pdata = (BYTE**)&settings->TargetNetAddress;
plen = &settings->TargetNetAddressCount;
break;
case FreeRDP_LoadBalanceInfo:

View File

@@ -0,0 +1,24 @@
From: Mike Gilbert <floppym@gentoo.org>
Date: Wed, 22 May 2024 17:04:43 -0400
Subject: X11: fix pointer/integer type mismatch
Fixed on master in 2da280b8a1748052b70b3f5a1ef0d8e932c33adc.
(cherry picked from commit d2b6771c748e54e659d5f1243a92e499c3beaa36)
---
client/X11/xf_graphics.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c
index 5aa1fd4..fe81e0e 100644
--- a/client/X11/xf_graphics.c
+++ b/client/X11/xf_graphics.c
@@ -438,7 +438,7 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
#endif
fail:
- WLog_DBG(TAG, "%s: %ld", __func__, rc ? pointer : -1);
+ WLog_DBG(TAG, "%s: %p", __func__, rc ? pointer : NULL);
return rc;
}

View File

@@ -0,0 +1,22 @@
From: akallabeth <akallabeth@posteo.net>
Date: Thu, 23 May 2024 09:30:33 +0200
Subject: [client,wayland] fix const correctness
(cherry picked from commit 67818bddb31900cdf3acb26cb0b673cc90b71cc9)
---
client/Wayland/wlfreerdp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c
index 65e29bc..5988aed 100644
--- a/client/Wayland/wlfreerdp.c
+++ b/client/Wayland/wlfreerdp.c
@@ -587,7 +587,7 @@ static void wlf_client_free(freerdp* instance, rdpContext* context)
DeleteCriticalSection(&wlf->critical);
}
-static void* uwac_event_clone(const void* val)
+static void* uwac_event_clone(void* val)
{
UwacEvent* copy;
UwacEvent* ev = (UwacEvent*)val;

View File

@@ -0,0 +1,89 @@
From: Armin Novak <armin.novak@thincast.com>
Date: Thu, 8 Aug 2024 11:03:24 +0200
Subject: [warnings] fix -Wincompatible-pointer-types
(cherry picked from commit 5b2b53b15c9af46b85c4ef0007e7fb59d7608289)
---
channels/ainput/server/ainput_main.c | 8 ++++----
libfreerdp/codec/dsp_ffmpeg.c | 2 +-
winpr/libwinpr/crt/unicode.c | 8 ++++----
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/channels/ainput/server/ainput_main.c b/channels/ainput/server/ainput_main.c
index 943d0fa..fc61f9b 100644
--- a/channels/ainput/server/ainput_main.c
+++ b/channels/ainput/server/ainput_main.c
@@ -222,7 +222,7 @@ static HANDLE ainput_server_get_channel_handle(ainput_server* ainput)
WINPR_ASSERT(ainput);
- if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualEventHandle, &buffer,
+ if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualEventHandle, (void**)&buffer,
&BytesReturned) == TRUE)
{
if (BytesReturned == sizeof(HANDLE))
@@ -416,7 +416,7 @@ ainput_server_context* ainput_server_context_new(HANDLE vcm)
goto fail;
return &ainput->context;
fail:
- ainput_server_context_free(ainput);
+ ainput_server_context_free(&ainput->context);
return NULL;
}
@@ -539,8 +539,8 @@ UINT ainput_server_context_poll_int(ainput_server_context* context)
BYTE* buffer = NULL;
DWORD BytesReturned = 0;
- if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualChannelReady, &buffer,
- &BytesReturned) != TRUE)
+ if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualChannelReady,
+ (void**)&buffer, &BytesReturned) != TRUE)
{
WLog_ERR(TAG, "WTSVirtualChannelReady failed,");
}
diff --git a/libfreerdp/codec/dsp_ffmpeg.c b/libfreerdp/codec/dsp_ffmpeg.c
index ef67914..80df188 100644
--- a/libfreerdp/codec/dsp_ffmpeg.c
+++ b/libfreerdp/codec/dsp_ffmpeg.c
@@ -423,7 +423,7 @@ static BOOL ffmpeg_encode_frame(AVCodecContext* context, AVFrame* in, AVPacket*
uint8_t** pp = in->extended_data;
for (int y = 0; y < in->channels; y++)
{
- float* data = pp[y];
+ float* data = (float*)pp[y];
for (int x = 0; x < in->nb_samples; x++)
{
const float val1 = data[x];
diff --git a/winpr/libwinpr/crt/unicode.c b/winpr/libwinpr/crt/unicode.c
index dc3533a..acbec01 100644
--- a/winpr/libwinpr/crt/unicode.c
+++ b/winpr/libwinpr/crt/unicode.c
@@ -215,8 +215,8 @@ int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int
else
{
targetLength =
- ucnv_convert("UTF-16LE", "UTF-8", targetStart, targetCapacity * sizeof(WCHAR),
- lpMultiByteStr, cbMultiByte, &error);
+ ucnv_convert("UTF-16LE", "UTF-8", (char*)targetStart,
+ targetCapacity * sizeof(WCHAR), lpMultiByteStr, cbMultiByte, &error);
if (targetLength > 0)
targetLength /= sizeof(WCHAR);
cchWideChar = U_SUCCESS(error) ? targetLength : 0;
@@ -353,14 +353,14 @@ int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int
#if defined(UCNV_CONVERT)
if (cbMultiByte == 0)
{
- targetLength = ucnv_convert("UTF-8", "UTF-16LE", NULL, 0, lpWideCharStr,
+ targetLength = ucnv_convert("UTF-8", "UTF-16LE", NULL, 0, (char*)lpWideCharStr,
cchWideChar * sizeof(WCHAR), &error);
cbMultiByte = targetLength;
}
else
{
targetLength = ucnv_convert("UTF-8", "UTF-16LE", targetStart, targetCapacity,
- lpWideCharStr, cchWideChar * sizeof(WCHAR), &error);
+ (char*)lpWideCharStr, cchWideChar * sizeof(WCHAR), &error);
cbMultiByte = U_SUCCESS(error) ? targetLength : 0;
}

View File

@@ -0,0 +1,48 @@
From: Armin Novak <armin.novak@thincast.com>
Date: Thu, 8 Aug 2024 11:06:54 +0200
Subject: [server,proxy] deactivate capture module
the module does not work (and did not for a long time)
(cherry picked from commit be23ed4ba990bd39391a651444fbb9130722c93b)
---
server/proxy/modules/capture/CMakeLists.txt | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/server/proxy/modules/capture/CMakeLists.txt b/server/proxy/modules/capture/CMakeLists.txt
index 80ba3b7..4004aaa 100644
--- a/server/proxy/modules/capture/CMakeLists.txt
+++ b/server/proxy/modules/capture/CMakeLists.txt
@@ -17,17 +17,19 @@
# limitations under the License.
#
-set(PLUGIN_NAME "proxy-capture-plugin")
+# deactivated: does not work
-add_library(${PLUGIN_NAME} MODULE
- cap_main.c
- cap_config.c
- cap_config.h
- cap_protocol.c
- cap_protocol.h
-)
-
-set_target_properties(${PLUGIN_NAME} PROPERTIES PREFIX "")
-set_target_properties(${PLUGIN_NAME} PROPERTIES NO_SONAME 1)
-set_target_properties(${PLUGIN_NAME} PROPERTIES
-LIBRARY_OUTPUT_DIRECTORY "${FREERDP_PROXY_PLUGINDIR}")
+#set(PLUGIN_NAME "proxy-capture-plugin")
+#
+#add_library(${PLUGIN_NAME} MODULE
+# cap_main.c
+# cap_config.c
+# cap_config.h
+# cap_protocol.c
+# cap_protocol.h
+#)
+#
+#set_target_properties(${PLUGIN_NAME} PROPERTIES PREFIX "")
+#set_target_properties(${PLUGIN_NAME} PROPERTIES NO_SONAME 1)
+#set_target_properties(${PLUGIN_NAME} PROPERTIES
+#LIBRARY_OUTPUT_DIRECTORY "${FREERDP_PROXY_PLUGINDIR}")

View File

@@ -0,0 +1,24 @@
From cd1ffa112cfbe1b40a9fd57e299a8ea12e23df0d Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Sat, 10 Jan 2026 08:36:38 +0100
Subject: [PATCH] [channels,audin] free up old audio formats
---
channels/audin/client/audin_main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c
index bcaf1a646265..b4c8ba58073a 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)

View File

@@ -0,0 +1,23 @@
From 3da319570c8a6be0a79b3306f1ed354c4a943259 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 12 Jan 2026 03:44:06 +0100
Subject: [PATCH] [channels,drive] fix constant type
ensure constant is of 64bit integer type
---
channels/drive/client/drive_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c
index 1dce5c348a61..13188fbc6427 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;

View File

@@ -0,0 +1,33 @@
From 675c20f08f32ca5ec06297108bdf30147d6e2cd9 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Tue, 13 Jan 2026 09:39:33 +0100
Subject: [PATCH] [channels,serial] explicitly lock serial->IrpThreads
---
channels/serial/client/serial_main.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
Index: freerdp-2.11.7/channels/serial/client/serial_main.c
===================================================================
--- freerdp-2.11.7.orig/channels/serial/client/serial_main.c
+++ freerdp-2.11.7/channels/serial/client/serial_main.c
@@ -595,7 +595,9 @@ static void create_irp_thread(SERIAL_DEV
* observed with FreeRDP).
*/
key = irp->CompletionId;
+ ListDictionary_Lock(serial->IrpThreads);
previousIrpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)key);
+ ListDictionary_Unlock(serial->IrpThreads);
if (previousIrpThread)
{
@@ -693,7 +695,9 @@ static void terminate_pending_irp_thread
WLog_Print(serial->log, WLOG_DEBUG, "IRP thread terminated, CompletionId %p", (void*)id);
}
+ ListDictionary_Lock(serial->IrpThreads);
ListDictionary_Clear(serial->IrpThreads);
+ ListDictionary_Unlock(serial->IrpThreads);
free(ids);
}

View File

@@ -0,0 +1,191 @@
From 7b7e6de8fe427a2f01d331056774aec69710590b Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
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(-)
Index: freerdp-2.11.7/channels/urbdrc/client/data_transfer.c
===================================================================
--- freerdp-2.11.7.orig/channels/urbdrc/client/data_transfer.c
+++ freerdp-2.11.7/channels/urbdrc/client/data_transfer.c
@@ -397,13 +397,12 @@ static void func_select_all_interface_fo
{
UINT32 inum;
MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces;
- BYTE InterfaceNumber, AlternateSetting;
UINT32 NumInterfaces = MsConfig->NumInterfaces;
for (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);
}
}
Index: freerdp-2.11.7/channels/urbdrc/client/libusb/libusb_udevice.c
===================================================================
--- freerdp-2.11.7.orig/channels/urbdrc/client/libusb/libusb_udevice.c
+++ freerdp-2.11.7/channels/urbdrc/client/libusb/libusb_udevice.c
@@ -571,25 +571,13 @@ static MSUSB_CONFIG_DESCRIPTOR*
libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsConfig)
{
UDEVICE* pdev = (UDEVICE*)idev;
- MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces;
- MSUSB_INTERFACE_DESCRIPTOR* MsInterface;
- MSUSB_PIPE_DESCRIPTOR** MsPipes;
- MSUSB_PIPE_DESCRIPTOR* MsPipe;
- MSUSB_PIPE_DESCRIPTOR** t_MsPipes;
- MSUSB_PIPE_DESCRIPTOR* t_MsPipe;
- LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig;
- const LIBUSB_INTERFACE* LibusbInterface;
- const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting;
- const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint;
- BYTE LibusbNumEndpoint;
- URBDRC_PLUGIN* urbdrc;
UINT32 inum = 0, pnum = 0, 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)
{
@@ -597,28 +585,56 @@ libusb_udev_complete_msconfig_setup(IUDE
"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 (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 (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;
@@ -656,10 +671,12 @@ libusb_udev_complete_msconfig_setup(IUDE
for (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 >>>||
@@ -674,15 +691,15 @@ libusb_udev_complete_msconfig_setup(IUDE
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 (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 >>>>>>>>>>>||
Index: freerdp-2.11.7/channels/urbdrc/common/msusb.c
===================================================================
--- freerdp-2.11.7.orig/channels/urbdrc/common/msusb.c
+++ freerdp-2.11.7/channels/urbdrc/common/msusb.c
@@ -139,6 +139,8 @@ BOOL msusb_msinterface_replace(MSUSB_CON
{
if (!MsConfig || !MsConfig->MsInterfaces)
return FALSE;
+ if (MsConfig->NumInterfaces <= InterfaceNumber)
+ return FALSE;
msusb_msinterface_free(MsConfig->MsInterfaces[InterfaceNumber]);
MsConfig->MsInterfaces[InterfaceNumber] = NewMsInterface;
@@ -147,12 +149,10 @@ BOOL msusb_msinterface_replace(MSUSB_CON
MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_read(wStream* s)
{
- MSUSB_INTERFACE_DESCRIPTOR* MsInterface;
-
if (Stream_GetRemainingCapacity(s) < 12)
return NULL;
- MsInterface = msusb_msinterface_new();
+ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = msusb_msinterface_new();
if (!MsInterface)
return NULL;

View File

@@ -0,0 +1,25 @@
From 1bab198a2edd0d0e6e1627d21a433151ea190500 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
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(+)
Index: freerdp-2.11.7/libfreerdp/codec/planar.c
===================================================================
--- freerdp-2.11.7.orig/libfreerdp/codec/planar.c
+++ freerdp-2.11.7/libfreerdp/codec/planar.c
@@ -616,6 +616,11 @@ BOOL planar_decompress(BITMAP_PLANAR_CON
WINPR_ASSERT(planar);
WINPR_ASSERT(prims);
+ if (planar->maxWidth < nSrcWidth)
+ return FALSE;
+ if (planar->maxHeight < nSrcHeight)
+ return FALSE;
+
if (nDstStep <= 0)
nDstStep = nDstWidth * GetBytesPerPixel(DstFormat);

View File

@@ -0,0 +1,69 @@
From 25102b432fb37916a1a553d7ef8fd940c6e52c3f Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Thu, 15 Jan 2026 12:17:33 +0100
Subject: [PATCH] [codec,clear] fix missing length checks
---
libfreerdp/codec/clear.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
Index: freerdp-2.11.7/libfreerdp/codec/clear.c
===================================================================
--- freerdp-2.11.7.orig/libfreerdp/codec/clear.c
+++ freerdp-2.11.7/libfreerdp/codec/clear.c
@@ -1141,7 +1141,54 @@ INT32 clear_decompress(CLEAR_CONTEXT* cl
if (glyphData)
{
- if (!freerdp_image_copy(glyphData, clear->format, 0, 0, 0, nWidth, nHeight, pDstData,
+ 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(glyphData, clear->format, 0, 0, 0, w, h, pDstData,
DstFormat, nDstStep, nXDst, nYDst, palette, FREERDP_FLIP_NONE))
goto fail;
}

View File

@@ -0,0 +1,44 @@
From c4a7c371342edf0d307cea728f56d3302f0ab38c Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
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(-)
Index: freerdp-2.11.7/libfreerdp/gdi/gfx.c
===================================================================
--- freerdp-2.11.7.orig/libfreerdp/gdi/gfx.c
+++ freerdp-2.11.7/libfreerdp/gdi/gfx.c
@@ -1175,7 +1175,6 @@ static UINT gdi_SurfaceToSurface(RdpgfxC
UINT status = ERROR_INTERNAL_ERROR;
UINT16 index;
BOOL sameSurface;
- UINT32 nWidth, nHeight;
const RECTANGLE_16* rectSrc;
RECTANGLE_16 invalidRect;
gdiGfxSurface* surfaceSrc;
@@ -1199,8 +1198,8 @@ static UINT gdi_SurfaceToSurface(RdpgfxC
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 (index = 0; index < surfaceToSurface->destPtsCount; index++)
{
@@ -1209,8 +1208,10 @@ static UINT gdi_SurfaceToSurface(RdpgfxC
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;

View File

@@ -0,0 +1,28 @@
From f8688b57f6cfad9a0b05475a6afbde355ffab720 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
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(-)
Index: freerdp-2.11.7/libfreerdp/codec/clear.c
===================================================================
--- freerdp-2.11.7.orig/libfreerdp/codec/clear.c
+++ freerdp-2.11.7/libfreerdp/codec/clear.c
@@ -883,11 +883,13 @@ static BOOL clear_decompress_bands_data(
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)
+ return FALSE;
BYTE* pDstPixel8 = &pDstData[((nYDstRel + y) * nDstStep) +
((nXDstRel + i) * GetBytesPerPixel(DstFormat))];
UINT32 color = ReadColor(cpSrcPixel, clear->format);

View File

@@ -0,0 +1,47 @@
From e02e052f6692550e539d10f99de9c35a23492db2 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
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)
{

View File

@@ -0,0 +1,25 @@
From d676518809c319eec15911c705c13536036af2ae Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 11:54:56 +0100
Subject: [PATCH] [channels,urbdrc] do not free MsConfig on failure
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))
{

View File

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

View File

@@ -0,0 +1,38 @@
From 2d563a50be17c1b407ca448b1321378c0726dd31 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:59:39 +0100
Subject: [PATCH] [channels,urbdrc] ensure InterfaceNumber is within range
---
channels/urbdrc/client/libusb/libusb_udevice.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff -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,

View File

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

View File

@@ -0,0 +1,22 @@
From 1c5c74223179d425a1ce6dbbb6a3dd2a958b7aee Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:14:08 +0100
Subject: [PATCH] [channels,audin] fix audin_server_recv_formats cleanup
---
channels/audin/server/audin.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
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;

View File

@@ -0,0 +1,116 @@
From d9ca272dce7a776ab475e9b1a8e8c3d2968c8486 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 12:08:48 +0100
Subject: [PATCH] [channels,ainput] lock context when updating listener
---
channels/ainput/client/ainput_main.c | 36 ++++++++++++++++++++--------
1 file changed, 26 insertions(+), 10 deletions(-)
diff -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);
}

View File

@@ -0,0 +1,112 @@
From afa6851dc80835d3101e40fcef51b6c5c0f43ea5 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Wed, 28 Jan 2026 09:31:06 +0100
Subject: [PATCH] [channel,rdpsnd] only clean up thread before free
rdpsnd channel usually has multiple instances (static, dynamic, ...) so
ensure only to terminate the handler thread when the channel is actually
closed for good.
---
channels/rdpsnd/client/rdpsnd_main.c | 43 ++++++++++++++++------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff -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;
}

View File

@@ -0,0 +1,60 @@
From 622bb7b4402491ca003f47472d0e478132673696 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:48:14 +0100
Subject: [PATCH] [channels,rdpsnd] terminate thread before free
Ensure that the optional rdpsnd thread is terminated and the message
queue freed up before releasing the channel context memory
---
channels/rdpsnd/client/rdpsnd_main.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff -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);

View File

@@ -1,3 +1,49 @@
-------------------------------------------------------------------
Wed Feb 18 22:16:47 UTC 2026 - Michael Gorse <mgorse@suse.com>
- 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)
-------------------------------------------------------------------
Fri Feb 6 07:57:57 UTC 2026 - Yifan Jiang <yfjiang@suse.com>
- Add patches to fix CVE issues:
+ freerdp-CVE-2026-22852.patch (CVE-2026-22852, bsc#1256718)
+ freerdp-CVE-2026-22854.patch (CVE-2026-22854, bsc#1256720)
+ freerdp-CVE-2026-22856.patch (CVE-2026-22856, bsc#1256722)
+ freerdp-CVE-2026-22859.patch (CVE-2026-22859, bsc#1256725)
+ freerdp-CVE-2026-23530.patch (CVE-2026-23530, bsc#1256940)
+ freerdp-CVE-2026-23531.patch (CVE-2026-23531, bsc#1256941)
+ freerdp-CVE-2026-23532.patch (CVE-2026-23532, bsc#1256942)
+ freerdp-CVE-2026-23534.patch (CVE-2026-23534, bsc#1256944)
-------------------------------------------------------------------
Fri Oct 24 07:57:48 UTC 2025 - Yifan Jiang <yfjiang@suse.com>
- Update 0001-Fix-build-with-ffmpeg-7.patch: fix build issue in
h264_ffmpeg.c.
-------------------------------------------------------------------
Sat Oct 5 08:05:54 UTC 2024 - Christophe Marin <christophe@krop.fr>
- Add upstream fixes (picked from Debian) (boo#1231317)
* 0001-info-Fix-incompatible-pointer-type.patch
* 0002-redirection-Fix-incompatible-pointer-type.patch
* 0003-redirection-Fix-incompatible-pointer-type.patch
* 0004-X11-fix-pointer-integer-type-mismatch.patch
* 0005-client-wayland-fix-const-correctness.patch
* 0006-warnings-fix-Wincompatible-pointer-types.patch
* 0007-server-proxy-deactivate-capture-module.patch
* 0001-Fix-build-with-ffmpeg-7.patch
-------------------------------------------------------------------
Mon Jun 3 16:39:14 UTC 2024 - Hans-Peter Jansen <hpj@urpla.net>
@@ -61,7 +107,7 @@ Tue Mar 26 09:28:11 UTC 2024 - Joan Torres <joan.torres@suse.com>
Thu Mar 14 19:55:22 UTC 2024 - Joan Torres <joan.torres@suse.com>
- Update to version 2.11.5:
* Fix integer overflow in progressive decoder
* Fix integer overflow in progressive decoder (bsc#1219049, CVE-2024-22211)
* Update OpenSSL API usage for compatiblility with newer versions (#9747)
* Prevent NULL dereference for single thread decoder (#9712)

View File

@@ -1,7 +1,7 @@
#
# spec file for package freerdp2
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -43,11 +43,55 @@ URL: https://www.freerdp.com/
Source0: https://github.com/FreeRDP/FreeRDP/releases/download/%{version}/freerdp-%{version}.tar.gz
Source1: freerdp2-rpmlintrc
# PATCH-FIX-UPSTREAM https://github.com/FreeRDP/FreeRDP/pull/7476
Patch1: 0001-Make-H.264-codec-optional-during-runtime.patch
Patch0: 0001-Make-H.264-codec-optional-during-runtime.patch
# PATCH-FIX-OPENSUSE -- Don't let 'cmake(WinPR)' require unneeded tools
Patch2: 0001-Don-t-add-winpr-cli-tools-to-exported-CMake-targets.patch
Patch1: 0001-Don-t-add-winpr-cli-tools-to-exported-CMake-targets.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2024-32661.patch CVE-2024-32661 bsc#1223348 yu.daike@suse.com -- client NULL pointer dereference
Patch3: freerdp-CVE-2024-32661.patch
Patch2: freerdp-CVE-2024-32661.patch
# PATCH-FIX-UPSTREAM -- gcc 14 compat
Patch3: 0001-info-Fix-incompatible-pointer-type.patch
Patch4: 0002-redirection-Fix-incompatible-pointer-type.patch
Patch5: 0003-redirection-Fix-incompatible-pointer-type.patch
Patch6: 0004-X11-fix-pointer-integer-type-mismatch.patch
Patch7: 0005-client-wayland-fix-const-correctness.patch
Patch8: 0006-warnings-fix-Wincompatible-pointer-types.patch
Patch9: 0007-server-proxy-deactivate-capture-module.patch
# PATCH-FIX-UPSTREAM -- ffmpeg 7 compat
Patch10: 0001-Fix-build-with-ffmpeg-7.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-22852.patch bsc#1256718 yfjiang@suse.com -- free up old audio formats
Patch12: freerdp-CVE-2026-22852.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-22854.patch bsc#1256720 yfjiang@suse.com -- fix constant type
Patch13: freerdp-CVE-2026-22854.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-22856.patch bsc#1256722 yfjiang@suse.com -- explicitly lock serial->IrpThreads
Patch15: freerdp-CVE-2026-22856.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-22859.patch bsc#1256725 yfjiang@suse.com -- check interface indices before use
Patch17: freerdp-CVE-2026-22859.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-23530.patch bsc#1256940 yfjiang@suse.com -- [codec,planar] fix decoder length checks
Patch18: freerdp-CVE-2026-23530.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-23531.patch bsc#1256941 yfjiang@suse.com -- [codec,clear] fix missing length checks
Patch19: freerdp-CVE-2026-23531.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-23532.patch bsc#1256942 yfjiang@suse.com -- [gdi,gfx] properly clamp SurfaceToSurface
Patch20: freerdp-CVE-2026-23532.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-23534.patch bsc#1256944 yfjiang@suse.com -- [codec,clear] fix off by one length check
Patch22: freerdp-CVE-2026-23534.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24491.patch bsc#1257981 mgorse@suse.com -- [channels,drdynvc] reset channel_callback before close
Patch23: freerdp-CVE-2026-24491.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24675.patch bsc#1257982 mgorse@suse.com -- [channels,urbdrc] do not free MsConfig on failure
Patch24: freerdp-CVE-2026-24675.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24676.patch bsc#1257983 mgorse@suse.com -- [channels,audin] reset audin->format
Patch25: freerdp-CVE-2026-24676.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24679.patch bsc#1257986 mgorse@suse.com -- [channels,urbdrc] ensure InterfaceNumber is within range
Patch26: freerdp-CVE-2026-24679.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24681.patch bsc#1257988 mgorse@suse.com -- [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 mgorse@suse.com -- [channels,audin] fix audin_server_recv_formats cleanup
Patch28: freerdp-CVE-2026-24682.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24683.patch bsc#1257990 mgorse@suse.com -- [channels,ainput] lock context when updating listener
Patch29: freerdp-CVE-2026-24683.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24684.patch bsc#1257991 mgorse@suse.com -- [channels,rdpsnd] terminate thread before free
Patch30: freerdp-CVE-2026-24684.patch
# PATCH-FIX-UPSTREAM freerdp-CVE-2026-24684-2.patch bsc#1257991 mgorse@suse.com -- [channel,rdpsnd] only clean up thread before free
Patch31: freerdp-CVE-2026-24684-2.patch
BuildRequires: cmake >= 2.8
BuildRequires: cups-devel
BuildRequires: ed