import Oracle_OSS freerdp-3.10.3-5.el10_1.8

This commit is contained in:
AlmaLinux RelEng Bot 2026-05-11 16:35:23 -04:00
parent acb0a4e76e
commit 6b0a8dd639
11 changed files with 944 additions and 1 deletions

View File

@ -0,0 +1,52 @@
From ce86fd834bc1002f3f4a827b73fbd1fdc870dc42 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 04:19:39 +0000
Subject: [PATCH] [cache,bitmap] initialize overallocated bitmap cache extra
slot
Backport of commit 8270e0bb3d6726c947d57c93ba9caa92a052b557.
Adjusted hunk offsets for 3.10.3.
Made-with: Cursor
---
libfreerdp/cache/bitmap.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/libfreerdp/cache/bitmap.c b/libfreerdp/cache/bitmap.c
index 8083fd9..1dc9853 100644
--- a/libfreerdp/cache/bitmap.c
+++ b/libfreerdp/cache/bitmap.c
@@ -390,6 +390,19 @@ rdpBitmapCache* bitmap_cache_new(rdpContext* context)
cell->number = nr;
}
+ /* initialize the overallocated extra slot for old RDP servers that send
+ * cacheId == maxCells; use a minimal allocation since no protocol-negotiated
+ * capacity exists for this slot */
+ {
+ BITMAP_V2_CELL* extra = &bitmapCache->cells[bitmapCache->maxCells];
+ /* allocate an extra entry for BITMAP_CACHE_WAITING_LIST_INDEX */
+ extra->entries = (rdpBitmap**)calloc(1, sizeof(rdpBitmap*));
+
+ if (!extra->entries)
+ goto fail;
+ extra->number = 0;
+ }
+
return bitmapCache;
fail:
WINPR_PRAGMA_DIAG_PUSH
@@ -408,7 +421,8 @@ void bitmap_cache_free(rdpBitmapCache* bitmapCache)
if (bitmapCache->cells)
{
- for (UINT32 i = 0; i < bitmapCache->maxCells; i++)
+ /* iterate through maxCells + 1 to also free the overallocated extra slot */
+ for (UINT32 i = 0; i <= bitmapCache->maxCells; i++)
{
UINT32 j = 0;
BITMAP_V2_CELL* cell = &bitmapCache->cells[i];
--
2.53.0

View File

@ -0,0 +1,33 @@
From 3c4666445b42c983a767e59888c5863bb420f331 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 04:19:33 +0000
Subject: [PATCH] [cache,bitmap] overallocate bitmap cache
Backport of commit ffad58fd2b329efd81a3239e9d7e3c927b8e503f.
Adjusted hunk offsets for 3.10.3.
Made-with: Cursor
---
libfreerdp/cache/bitmap.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/libfreerdp/cache/bitmap.c b/libfreerdp/cache/bitmap.c
index 6b6463c..8083fd9 100644
--- a/libfreerdp/cache/bitmap.c
+++ b/libfreerdp/cache/bitmap.c
@@ -367,7 +367,10 @@ rdpBitmapCache* bitmap_cache_new(rdpContext* context)
const UINT32 BitmapCacheV2NumCells =
freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells);
bitmapCache->context = context;
- bitmapCache->cells = (BITMAP_V2_CELL*)calloc(BitmapCacheV2NumCells, sizeof(BITMAP_V2_CELL));
+
+ /* overallocate by 1. older RDP servers do send a off by 1 cache index. */
+ bitmapCache->cells =
+ (BITMAP_V2_CELL*)calloc(BitmapCacheV2NumCells + 1ull, sizeof(BITMAP_V2_CELL));
if (!bitmapCache->cells)
goto fail;
--
2.53.0

View File

@ -0,0 +1,47 @@
From 4d45e4715adfa57dfc0a829ec351dbe2680e756b Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 05:15:25 +0000
Subject: [PATCH] [cache,persist] use winpr_aligned_calloc
Backport of commit a48dbde2c8a5b8b70a9d1c045d969a71afd6284c.
`nullptr` replaced with `NULL` (not available in 3.10.3).
Made-with: Cursor
---
libfreerdp/cache/persistent.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libfreerdp/cache/persistent.c b/libfreerdp/cache/persistent.c
index 39be803..e963c5e 100644
--- a/libfreerdp/cache/persistent.c
+++ b/libfreerdp/cache/persistent.c
@@ -39,6 +39,7 @@ struct rdp_persistent_cache
size_t bmpSize;
};
+static const size_t PERSIST_ALIGN = 32;
static const char sig_str[] = "RDP8bmp";
int persistent_cache_get_version(rdpPersistentCache* persistent)
@@ -155,7 +156,7 @@ static int persistent_cache_read_entry_v3(rdpPersistentCache* persistent,
{
persistent->bmpSize = size;
BYTE* bmpData = (BYTE*)winpr_aligned_recalloc(persistent->bmpData, persistent->bmpSize,
- sizeof(BYTE), 32);
+ sizeof(BYTE), PERSIST_ALIGN);
if (!bmpData)
return -1;
@@ -350,7 +351,7 @@ rdpPersistentCache* persistent_cache_new(void)
return NULL;
persistent->bmpSize = 0x4000;
- persistent->bmpData = calloc(1, persistent->bmpSize);
+ persistent->bmpData = winpr_aligned_calloc(1, persistent->bmpSize, PERSIST_ALIGN);
if (!persistent->bmpData)
{
--
2.53.0

View File

@ -0,0 +1,54 @@
From 1d86433a0f30490e1e0fdc3bb8f76d259ef67a9d Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 05:14:58 +0000
Subject: [PATCH] [cache,persistent] update PERSISTENT_CACHE_ENTRY::size after
realloc
Backport of commit 1a890eb43492b5eb707cb3dd6fc908f696e8fc1c.
WINPR_ASSERTING_INT_CAST replaced with plain cast (macro not available in 3.10.3).
Made-with: Cursor
---
libfreerdp/cache/persistent.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libfreerdp/cache/persistent.c b/libfreerdp/cache/persistent.c
index 16025b8..39be803 100644
--- a/libfreerdp/cache/persistent.c
+++ b/libfreerdp/cache/persistent.c
@@ -36,7 +36,7 @@ struct rdp_persistent_cache
int count;
char* filename;
BYTE* bmpData;
- UINT32 bmpSize;
+ size_t bmpSize;
};
static const char sig_str[] = "RDP8bmp";
@@ -149,12 +149,11 @@ static int persistent_cache_read_entry_v3(rdpPersistentCache* persistent,
const UINT64 size = 4ull * entry3.width * entry3.height;
if (size > UINT32_MAX)
return -1;
- entry->size = (UINT32)size;
entry->flags = 0;
- if (entry->size > persistent->bmpSize)
+ if (size > persistent->bmpSize)
{
- persistent->bmpSize = entry->size;
+ persistent->bmpSize = size;
BYTE* bmpData = (BYTE*)winpr_aligned_recalloc(persistent->bmpData, persistent->bmpSize,
sizeof(BYTE), 32);
@@ -163,6 +162,7 @@ static int persistent_cache_read_entry_v3(rdpPersistentCache* persistent,
persistent->bmpData = bmpData;
}
+ entry->size = (UINT32)size;
entry->data = persistent->bmpData;
--
2.53.0

View File

@ -0,0 +1,64 @@
From d9f55987f530bc881556fa61512865f4b07b1bb6 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Mon, 27 Apr 2026 14:53:46 +0000
Subject: [PATCH] [client,X11] fix clipboard update
Backport of commit 58409406afe7c2a8a71ed2dc8e22075be4f41c0c.
Adjusted hunk offsets for 3.10.3.
Made-with: Cursor
---
client/X11/xf_cliprdr.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c
index 265a66d..7a8ef71 100644
--- a/client/X11/xf_cliprdr.c
+++ b/client/X11/xf_cliprdr.c
@@ -850,7 +850,11 @@ static void xf_clipboard_formats_free(xfClipboard* clipboard)
{
WINPR_ASSERT(clipboard);
+ /* Synchronize RDP/X11 thread with channel thread */
+ xf_lock_x11(clipboard->xfc);
xf_cliprdr_free_formats(clipboard->lastSentFormats, clipboard->lastSentNumFormats);
+ xf_unlock_x11(clipboard->xfc);
+
clipboard->lastSentFormats = NULL;
clipboard->lastSentNumFormats = 0;
}
@@ -1862,24 +1866,23 @@ static UINT xf_cliprdr_send_client_format_list_response(xfClipboard* clipboard,
static UINT xf_cliprdr_monitor_ready(CliprdrClientContext* context,
const CLIPRDR_MONITOR_READY* monitorReady)
{
- UINT ret = 0;
- xfClipboard* clipboard = NULL;
-
WINPR_ASSERT(context);
WINPR_ASSERT(monitorReady);
- clipboard = cliprdr_file_context_get_context(context->custom);
+ xfClipboard* clipboard = cliprdr_file_context_get_context(context->custom);
WINPR_ASSERT(clipboard);
WINPR_UNUSED(monitorReady);
- if ((ret = xf_cliprdr_send_client_capabilities(clipboard)) != CHANNEL_RC_OK)
+ const UINT ret = xf_cliprdr_send_client_capabilities(clipboard);
+ if (ret != CHANNEL_RC_OK)
return ret;
xf_clipboard_formats_free(clipboard);
- if ((ret = xf_cliprdr_send_client_format_list(clipboard, TRUE)) != CHANNEL_RC_OK)
- return ret;
+ const UINT ret2 = xf_cliprdr_send_client_format_list(clipboard, TRUE);
+ if (ret2 != CHANNEL_RC_OK)
+ return ret2;
clipboard->sync = TRUE;
return CHANNEL_RC_OK;
--
2.53.0

View File

@ -0,0 +1,39 @@
From 3ac579a0844c200b71e160dd49208bc53ce06e8d Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 18:37:44 +0000
Subject: [PATCH] [client,X11] fix residual race in xf_clipboard_formats_free
Backport of commit 4c9f7e8a7129c8be15f6e2686559d3f17936677d.
Adjusted hunk offsets for 3.10.3, `nullptr` replaced with `NULL`.
Made-with: Cursor
---
client/X11/xf_cliprdr.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c
index 7a8ef71..82878e7 100644
--- a/client/X11/xf_cliprdr.c
+++ b/client/X11/xf_cliprdr.c
@@ -850,13 +850,14 @@ static void xf_clipboard_formats_free(xfClipboard* clipboard)
{
WINPR_ASSERT(clipboard);
- /* Synchronize RDP/X11 thread with channel thread */
+ /* Synchronize RDP/X11 thread with channel thread.
+ * Reset the pointer and count inside the lock so that
+ * xf_clipboard_changed cannot observe a freed-but-non-NULL pointer. */
xf_lock_x11(clipboard->xfc);
xf_cliprdr_free_formats(clipboard->lastSentFormats, clipboard->lastSentNumFormats);
- xf_unlock_x11(clipboard->xfc);
-
clipboard->lastSentFormats = NULL;
clipboard->lastSentNumFormats = 0;
+ xf_unlock_x11(clipboard->xfc);
}
static BOOL xf_clipboard_copy_formats(xfClipboard* clipboard, const CLIPRDR_FORMAT* formats,
--
2.53.0

View File

@ -0,0 +1,45 @@
From 97d6df1ca09102ca95ada1ae3ef9284881b2130c Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Mon, 27 Apr 2026 14:52:49 +0000
Subject: [PATCH] [client,x11] fix xf_rail_window_common cleanup
Backport of commit b4f0f0a18fe53aa8d47d062f91471f4e9c5e0d51.
Adjusted hunk offsets for 3.10.3.
Made-with: Cursor
---
client/X11/xf_rail.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c
index 5c42f7a..afcfc67 100644
--- a/client/X11/xf_rail.c
+++ b/client/X11/xf_rail.c
@@ -307,11 +307,10 @@ static void window_state_log_style_int(wLog* log, const WINDOW_STATE_ORDER* wind
static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
const WINDOW_STATE_ORDER* windowState)
{
- xfAppWindow* appWindow = NULL;
xfContext* xfc = (xfContext*)context;
UINT32 fieldFlags = orderInfo->fieldFlags;
BOOL position_or_size_updated = FALSE;
- appWindow = xf_rail_get_window(xfc, orderInfo->windowId);
+ xfAppWindow* appWindow = xf_rail_get_window(xfc, orderInfo->windowId);
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
{
@@ -362,10 +361,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
}
if (!appWindow->title)
- {
- free(appWindow);
return FALSE;
- }
xf_AppWindowInit(xfc, appWindow);
}
--
2.53.0

View File

@ -0,0 +1,58 @@
From daa338be37d8fdc8c4c924b5e868f5b979e49065 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 05:15:04 +0000
Subject: [PATCH] [codec,clear] Update CLEAR_GLYPH_ENTRY::count after alloc
Backport of commit c49d1ad43b8c7b32794d0250f2623c2dccd7ef25.
WINPR_ASSERTING_INT_CAST replaced with plain cast (macro not available in 3.10.3).
Made-with: Cursor
---
libfreerdp/codec/clear.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c
index 2d58aba..8b1571a 100644
--- a/libfreerdp/codec/clear.c
+++ b/libfreerdp/codec/clear.c
@@ -980,20 +980,30 @@ static BOOL clear_decompress_glyph_data(CLEAR_CONTEXT* WINPR_RESTRICT clear,
{
const UINT32 bpp = FreeRDPGetBytesPerPixel(clear->format);
CLEAR_GLYPH_ENTRY* glyphEntry = &(clear->GlyphCache[glyphIndex]);
- glyphEntry->count = nWidth * nHeight;
+ const size_t count = 1ull * nWidth * nHeight;
+ const size_t hlimit = SIZE_MAX / ((nWidth > 0) ? nWidth : 1);
+ if ((nWidth == 0) || (nHeight == 0) || (hlimit < nHeight))
+ {
+ const char* exceeded = (hlimit < nHeight) ? "within" : "outside";
+ WLog_ERR(TAG,
+ "CLEARCODEC_FLAG_GLYPH_INDEX: nWidth=%" PRIu32 ", nHeight=%" PRIu32
+ ", nWidth * nHeight is %s allowed range",
+ nWidth, nHeight, exceeded);
+ return FALSE;
+ }
- if (glyphEntry->count > glyphEntry->size)
+ if (count > glyphEntry->size)
{
- BYTE* tmp =
- winpr_aligned_recalloc(glyphEntry->pixels, glyphEntry->count, 1ull * bpp, 32);
+ BYTE* tmp = winpr_aligned_recalloc(glyphEntry->pixels, count, 1ull * bpp, 32);
if (!tmp)
{
- WLog_ERR(TAG, "glyphEntry->pixels winpr_aligned_recalloc %" PRIu32 " failed!",
- glyphEntry->count * bpp);
+ WLog_ERR(TAG, "glyphEntry->pixels winpr_aligned_recalloc %" PRIuz " failed!",
+ count * bpp);
return FALSE;
}
+ glyphEntry->count = (UINT32)count;
glyphEntry->size = glyphEntry->count;
glyphEntry->pixels = (UINT32*)tmp;
}
--
2.53.0

View File

@ -0,0 +1,277 @@
From 81283063b678b6582244a0f32f2059c8d8bba8cb Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 04:41:15 +0000
Subject: [PATCH] [codec,dsp] add format checks
Backport of commit 03b48b3601d867afccac1cdc6081de7a275edce7.
Adapted for 3.10.x: `nullptr` replaced with `NULL`,
`Stream_ResetPosition` replaced with `Stream_SetPosition`,
`error != nullptr` replaced with `error != NULL`.
Made-with: Cursor
---
libfreerdp/codec/dsp.c | 148 +++++++++++++++++++++++++++++++----------
1 file changed, 112 insertions(+), 36 deletions(-)
diff --git a/libfreerdp/codec/dsp.c b/libfreerdp/codec/dsp.c
index c5f5949..5e0f78a 100644
--- a/libfreerdp/codec/dsp.c
+++ b/libfreerdp/codec/dsp.c
@@ -354,11 +354,28 @@ static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, unsigned
return (UINT16)d;
}
+static BOOL valid_ima_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
+{
+ WINPR_ASSERT(context);
+ if (context->common.format.wFormatTag != WAVE_FORMAT_DVI_ADPCM)
+ return FALSE;
+ if (context->common.format.nBlockAlign <= 4ULL)
+ return FALSE;
+ if (context->common.format.nChannels < 1)
+ return FALSE;
+ if (context->common.format.wBitsPerSample == 0)
+ return FALSE;
+ return TRUE;
+}
+
static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
const BYTE* WINPR_RESTRICT src, size_t size,
wStream* WINPR_RESTRICT out)
{
- size_t out_size = size * 4;
+ if (!valid_ima_adpcm_format(context))
+ return FALSE;
+
+ size_t out_size = size * 4ull;
const UINT32 block_size = context->common.format.nBlockAlign;
const UINT32 channels = context->common.format.nChannels;
@@ -501,27 +518,38 @@ static BOOL freerdp_dsp_encode_gsm610(FREERDP_DSP_CONTEXT* WINPR_RESTRICT contex
#endif
#if defined(WITH_LAME)
+static BOOL valid_mp3_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
+{
+ WINPR_ASSERT(context);
+ if (context->common.format.wFormatTag != WAVE_FORMAT_MPEGLAYER3)
+ return FALSE;
+ if (context->common.format.nChannels < 1)
+ return FALSE;
+ if (context->common.format.wBitsPerSample == 0)
+ return FALSE;
+ if (context->common.format.nSamplesPerSec == 0)
+ return FALSE;
+ return TRUE;
+}
+
static BOOL freerdp_dsp_decode_mp3(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
const BYTE* WINPR_RESTRICT src, size_t size,
wStream* WINPR_RESTRICT out)
{
- int rc;
- short* pcm_l;
- short* pcm_r;
- size_t buffer_size;
-
if (!context || !src || !out)
return FALSE;
-
- buffer_size = 2 * context->common.format.nChannels * context->common.format.nSamplesPerSec;
+ if (!valid_mp3_format(context))
+ return FALSE;
+ const size_t buffer_size =
+ 2 * context->common.format.nChannels * context->common.format.nSamplesPerSec;
if (!Stream_EnsureCapacity(context->common.buffer, 2 * buffer_size))
return FALSE;
- pcm_l = Stream_BufferAs(context->common.buffer, short);
- pcm_r = Stream_BufferAs(context->common.buffer, short) + buffer_size;
- rc = hip_decode(context->hip, (unsigned char*)/* API is not modifying content */ src, size,
- pcm_l, pcm_r);
+ short* pcm_l = Stream_BufferAs(context->common.buffer, short);
+ short* pcm_r = Stream_BufferAs(context->common.buffer, short) + buffer_size;
+ const int rc = hip_decode(context->hip, (unsigned char*)/* API is not modifying content */ src,
+ size, pcm_l, pcm_r);
if (rc <= 0)
return FALSE;
@@ -542,13 +570,13 @@ static BOOL freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
const BYTE* WINPR_RESTRICT src, size_t size,
wStream* WINPR_RESTRICT out)
{
- size_t samples_per_channel;
- int rc;
-
if (!context || !src || !out)
return FALSE;
- samples_per_channel =
+ if (!valid_mp3_format(context))
+ return FALSE;
+
+ size_t samples_per_channel =
size / context->common.format.nChannels / context->common.format.wBitsPerSample / 8;
/* Ensure worst case buffer size for mp3 stream taken from LAME header */
@@ -556,8 +584,9 @@ static BOOL freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
return FALSE;
samples_per_channel = size / 2 /* size of a sample */ / context->common.format.nChannels;
- rc = lame_encode_buffer_interleaved(context->lame, (short*)src, samples_per_channel,
- Stream_Pointer(out), Stream_GetRemainingCapacity(out));
+ const int rc =
+ lame_encode_buffer_interleaved(context->lame, (short*)src, samples_per_channel,
+ Stream_Pointer(out), Stream_GetRemainingCapacity(out));
if (rc < 0)
return FALSE;
@@ -807,6 +836,8 @@ static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT con
const BYTE* WINPR_RESTRICT src, size_t size,
wStream* WINPR_RESTRICT out)
{
+ if (!valid_ima_adpcm_format(context))
+ return FALSE;
if (!Stream_EnsureRemainingCapacity(out, size))
return FALSE;
if (!Stream_EnsureRemainingCapacity(context->common.buffer, size + 64))
@@ -889,6 +920,20 @@ static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
+static BOOL valid_ms_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
+{
+ WINPR_ASSERT(context);
+ if (context->common.format.wFormatTag != WAVE_FORMAT_ADPCM)
+ return FALSE;
+ if (context->common.format.nBlockAlign <= 4ULL)
+ return FALSE;
+ if (context->common.format.nChannels < 1)
+ return FALSE;
+ if (context->common.format.wBitsPerSample == 0)
+ return FALSE;
+ return TRUE;
+}
+
static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, BYTE sample,
int channel)
{
@@ -918,6 +963,8 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
const BYTE* WINPR_RESTRICT src, size_t size,
wStream* WINPR_RESTRICT out)
{
+ if (!valid_ms_adpcm_format(context))
+ return FALSE;
const size_t out_size = size * 4;
const UINT32 channels = context->common.format.nChannels;
const UINT32 block_size = context->common.format.nBlockAlign;
@@ -1038,6 +1085,9 @@ static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
const BYTE* WINPR_RESTRICT src, size_t size,
wStream* WINPR_RESTRICT out)
{
+ if (!valid_ms_adpcm_format(context))
+ return FALSE;
+
const size_t step = 8 + ((context->common.format.nChannels > 1) ? 4 : 0);
if (!Stream_EnsureRemainingCapacity(out, size))
@@ -1482,21 +1532,44 @@ BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
context->common.format = *targetFormat;
- if (context->common.format.wFormatTag == WAVE_FORMAT_DVI_ADPCM)
+ switch (context->common.format.wFormatTag)
{
- size_t min_frame_data = 1ull * context->common.format.wBitsPerSample *
- context->common.format.nChannels * FramesPerPacket;
- size_t data_per_block =
- (1ULL * context->common.format.nBlockAlign - 4ULL * context->common.format.nChannels) *
- 8ULL;
- size_t nb_block_per_packet = min_frame_data / data_per_block;
-
- if (min_frame_data % data_per_block)
- nb_block_per_packet++;
-
- context->adpcm.ima.packet_size = nb_block_per_packet * context->common.format.nBlockAlign;
- Stream_EnsureCapacity(context->common.buffer, context->adpcm.ima.packet_size);
- Stream_SetPosition(context->common.buffer, 0);
+#if defined(WITH_LAME)
+ case WAVE_FORMAT_MPEGLAYER3:
+ if (!valid_mp3_format(context))
+ return FALSE;
+ break;
+#endif
+ case WAVE_FORMAT_ADPCM:
+ if (!valid_ms_adpcm_format(context))
+ return FALSE;
+ break;
+ case WAVE_FORMAT_DVI_ADPCM:
+ {
+ if (!valid_ima_adpcm_format(context))
+ return FALSE;
+ if (FramesPerPacket == 0)
+ return FALSE;
+
+ const size_t min_frame_data = 1ull * context->common.format.wBitsPerSample *
+ context->common.format.nChannels * FramesPerPacket;
+ const size_t data_per_block = (1ULL * context->common.format.nBlockAlign -
+ 4ULL * context->common.format.nChannels) *
+ 8ULL;
+ size_t nb_block_per_packet = min_frame_data / data_per_block;
+
+ if (min_frame_data % data_per_block)
+ nb_block_per_packet++;
+
+ context->adpcm.ima.packet_size =
+ nb_block_per_packet * context->common.format.nBlockAlign;
+ if (!Stream_EnsureCapacity(context->common.buffer, context->adpcm.ima.packet_size))
+ return FALSE;
+ Stream_SetPosition(context->common.buffer, 0);
+ }
+ break;
+ default:
+ break;
}
#if defined(WITH_OPUS)
@@ -1539,7 +1612,7 @@ BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
if (context->common.encoder)
{
- faacEncConfigurationPtr cfg;
+ faacEncConfigurationPtr cfg = NULL;
if (context->faac)
faacEncClose(context->faac);
@@ -1556,20 +1629,23 @@ BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
cfg->mpegVersion = MPEG4;
cfg->useTns = 1;
cfg->bandWidth = targetFormat->nAvgBytesPerSec;
- faacEncSetConfiguration(context->faac, cfg);
+ const int rc = faacEncSetConfiguration(context->faac, cfg);
+ if (rc <= 0)
+ return FALSE;
}
#endif
#if defined(WITH_SOXR)
{
soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
- soxr_error_t error;
+ soxr_error_t error = NULL;
+
soxr_delete(context->sox);
context->sox =
soxr_create(context->common.format.nSamplesPerSec, targetFormat->nSamplesPerSec,
targetFormat->nChannels, &error, &iospec, NULL, NULL);
- if (!context->sox || (error != 0))
+ if (!context->sox || (error != NULL))
return FALSE;
}
#endif
--
2.53.0

View File

@ -0,0 +1,224 @@
From 3bd10b4f0ea8c5a7e2da2b8d00a15b6ddf26e66f Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Tue, 28 Apr 2026 04:41:15 +0000
Subject: [PATCH] [codec,dsp] fix array bounds checks
Backport of commit 16df2300e1e3f5a51f68fb1626429e58b531b7c8.
Adapted for 3.10.x: kept `int channel` parameter type in
`dsp_encode_ima_adpcm_sample` (not `size_t`), kept `+=` style
for step index updates.
Made-with: Cursor
---
libfreerdp/codec/dsp.c | 79 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 70 insertions(+), 9 deletions(-)
diff --git a/libfreerdp/codec/dsp.c b/libfreerdp/codec/dsp.c
index 5e0f78a..b672074 100644
--- a/libfreerdp/codec/dsp.c
+++ b/libfreerdp/codec/dsp.c
@@ -321,7 +321,14 @@ static const INT16 ima_step_size_table[] = {
static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, unsigned int channel,
BYTE sample)
{
- const INT32 ss = ima_step_size_table[adpcm->ima.last_step[channel]];
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_step));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_sample));
+
+ const INT16 offset = adpcm->ima.last_step[channel];
+ WINPR_ASSERT(offset >= 0);
+ WINPR_ASSERT(offset < ARRAYSIZE(ima_step_size_table));
+
+ const INT32 ss = ima_step_size_table[offset];
INT32 d = (ss >> 3);
if (sample & 1)
@@ -344,6 +351,8 @@ static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, unsigned
d = 32767;
adpcm->ima.last_sample[channel] = (INT16)d;
+
+ WINPR_ASSERT(sample < ARRAYSIZE(ima_step_index_table));
adpcm->ima.last_step[channel] += ima_step_index_table[sample];
if (adpcm->ima.last_step[channel] < 0)
@@ -386,6 +395,9 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT con
{
if (size % block_size == 0)
{
+ if (size < 4)
+ return FALSE;
+
context->adpcm.ima.last_sample[0] =
(INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
context->adpcm.ima.last_step[0] = (INT16)(*(src + 2));
@@ -395,6 +407,8 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT con
if (channels > 1)
{
+ if (size < 4)
+ return FALSE;
context->adpcm.ima.last_sample[1] =
(INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
context->adpcm.ima.last_step[1] = (INT16)(*(src + 2));
@@ -406,6 +420,8 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT con
if (channels > 1)
{
+ if (size < 8)
+ return FALSE;
for (size_t i = 0; i < 8; i++)
{
BYTE* dst = Stream_Pointer(out);
@@ -434,6 +450,8 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT con
}
else
{
+ if (size < 1)
+ return FALSE;
BYTE* dst = Stream_Pointer(out);
if (!Stream_SafeSeek(out, 4))
return FALSE;
@@ -775,7 +793,14 @@ static const struct
static BYTE dsp_encode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, int channel, INT16 sample)
{
- INT32 ss = ima_step_size_table[adpcm->ima.last_step[channel]];
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_step));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_sample));
+
+ const INT16 offset = adpcm->ima.last_step[channel];
+ WINPR_ASSERT(offset >= 0);
+ WINPR_ASSERT(offset < ARRAYSIZE(ima_step_size_table));
+
+ INT32 ss = ima_step_size_table[offset];
INT32 e = sample - adpcm->ima.last_sample[channel];
INT32 d = e;
INT32 diff = ss >> 3;
@@ -822,6 +847,8 @@ static BYTE dsp_encode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, int channel
diff = 32767;
adpcm->ima.last_sample[channel] = (INT16)diff;
+
+ WINPR_ASSERT(enc < ARRAYSIZE(ima_step_index_table));
adpcm->ima.last_step[channel] += ima_step_index_table[enc];
if (adpcm->ima.last_step[channel] < 0)
@@ -937,11 +964,22 @@ static BOOL valid_ms_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, BYTE sample,
int channel)
{
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
+
const INT8 nibble = (sample & 0x08 ? (INT8)sample - 16 : (INT8)sample);
+ const BYTE predictor = adpcm->ms.predictor[channel];
+ INT32 coeff1 = 0;
+ if (predictor < ARRAYSIZE(ms_adpcm_coeffs1))
+ coeff1 = ms_adpcm_coeffs1[predictor];
+
+ INT32 coeff2 = 0;
+ if (predictor < ARRAYSIZE(ms_adpcm_coeffs2))
+ coeff2 = ms_adpcm_coeffs2[predictor];
INT32 presample =
- ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
- (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
- 256;
+ ((adpcm->ms.sample1[channel] * coeff1) + (adpcm->ms.sample2[channel] * coeff2)) / 256;
presample += nibble * adpcm->ms.delta[channel];
if (presample > 32767)
@@ -951,7 +989,12 @@ static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adp
adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
adpcm->ms.sample1[channel] = presample;
- adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[sample] / 256;
+
+ INT32 tableval = 0;
+ if (sample < ARRAYSIZE(ms_adpcm_adaptation_table))
+ tableval = ms_adpcm_adaptation_table[sample];
+
+ adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * tableval / 256;
if (adpcm->ms.delta[channel] < 16)
adpcm->ms.delta[channel] = 16;
@@ -978,6 +1021,9 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
{
if (channels > 1)
{
+ if (size < 14)
+ return FALSE;
+
context->adpcm.ms.predictor[0] = *src++;
context->adpcm.ms.predictor[1] = *src++;
context->adpcm.ms.delta[0] = read_int16(src);
@@ -1000,6 +1046,9 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
}
else
{
+ if (size < 7)
+ return FALSE;
+
context->adpcm.ms.predictor[0] = *src++;
context->adpcm.ms.delta[0] = read_int16(src);
src += 2;
@@ -1016,6 +1065,8 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
if (channels > 1)
{
{
+ if (size < 1)
+ return FALSE;
const BYTE sample = *src++;
size--;
Stream_Write_INT16(
@@ -1024,6 +1075,8 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
}
{
+ if (size < 1)
+ return FALSE;
const BYTE sample = *src++;
size--;
Stream_Write_INT16(
@@ -1034,6 +1087,8 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
}
else
{
+ if (size < 1)
+ return FALSE;
const BYTE sample = *src++;
size--;
Stream_Write_INT16(out,
@@ -1047,8 +1102,13 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT cont
}
static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, INT32 sample,
- int channel)
+ size_t channel)
{
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
+ WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
+
INT32 presample =
((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
(adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
@@ -1072,8 +1132,9 @@ static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, INT3
adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
adpcm->ms.sample1[channel] = presample;
- adpcm->ms.delta[channel] =
- adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[(((BYTE)errordelta) & 0x0F)] / 256;
+ const size_t offset = (((BYTE)errordelta) & 0x0F);
+ WINPR_ASSERT(offset < ARRAYSIZE(ms_adpcm_adaptation_table));
+ adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[offset] / 256;
if (adpcm->ms.delta[channel] < 16)
adpcm->ms.delta[channel] = 16;
--
2.53.0

View File

@ -30,7 +30,7 @@
Name: freerdp
Epoch: 2
Version: 3.10.3
Release: 5%{?dist}.6
Release: 5%{?dist}.8
Summary: Free implementation of the Remote Desktop Protocol (RDP)
# The effective license is Apache-2.0 but:
@ -190,6 +190,43 @@ Patch: codec-clear-update-CLEAR_VBAR_ENTRY-size-after-alloc.patch
Patch: codec-progressive-fail-progressive_rfx_quant_sub-on-invalid-values.patch
Patch: codec-progressive-fix-underflow-guard-in-progressive_rfx_quant_sub.patch
# CVE-2026-26986
# https://github.com/FreeRDP/FreeRDP/commit/b4f0f0a18fe53aa8d47d062f91471f4e9c5e0d51
Patch: client-x11-fix-xf_rail_window_common-cleanup.patch
# CVE-2026-25997
# https://github.com/FreeRDP/FreeRDP/commit/58409406afe7c2a8a71ed2dc8e22075be4f41c0c
# https://github.com/FreeRDP/FreeRDP/commit/4c9f7e8a7129c8be15f6e2686559d3f17936677d
Patch: client-x11-fix-clipboard-update.patch
Patch: client-x11-fix-residual-race-in-xf_clipboard_formats_free.patch
# CVE-2026-29775
# https://github.com/FreeRDP/FreeRDP/commit/ffad58fd2b329efd81a3239e9d7e3c927b8e503f
# https://github.com/FreeRDP/FreeRDP/commit/8270e0bb3d6726c947d57c93ba9caa92a052b557
Patch: cache-bitmap-overallocate-bitmap-cache.patch
Patch: cache-bitmap-initialize-overallocated-bitmap-cache-extra-slot.patch
# CVE-2026-31884
# https://github.com/FreeRDP/FreeRDP/commit/03b48b3601d867afccac1cdc6081de7a275edce7
Patch: codec-dsp-add-format-checks.patch
# CVE-2026-31883
# CVE-2026-31885
# https://github.com/FreeRDP/FreeRDP/commit/16df2300e1e3f5a51f68fb1626429e58b531b7c8
Patch: codec-dsp-fix-array-bounds-checks.patch
# CVE-2026-33987
# https://github.com/FreeRDP/FreeRDP/commit/1a890eb43492b5eb707cb3dd6fc908f696e8fc1c
Patch: cache-persistent-update-persistent_cache_entry-size-after-realloc.patch
# CVE-2026-33985
# https://github.com/FreeRDP/FreeRDP/commit/c49d1ad43b8c7b32794d0250f2623c2dccd7ef25
Patch: codec-clear-update-clear_glyph_entry-count-after-alloc.patch
# CVE-2026-33982
# https://github.com/FreeRDP/FreeRDP/commit/a48dbde2c8a5b8b70a9d1c045d969a71afd6284c
Patch: cache-persist-use-winpr_aligned_calloc.patch
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: alsa-lib-devel
@ -512,6 +549,19 @@ find %{buildroot} -name "*.a" -delete
%{_libdir}/pkgconfig/winpr-tools3.pc
%changelog
* Wed Apr 29 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.8
- Fix double free in xf_rail_window_common cleanup (CVE-2026-26986)
- Fix clipboard use-after-free during auto-reconnect (CVE-2026-25997)
- Fix heap-buffer-overflow in bitmap_cache_put (CVE-2026-29775)
- Add DSP format checks (CVE-2026-31884)
- Fix DSP array bounds checks (CVE-2026-31883)
- Fix DSP array bounds checks (CVE-2026-31885)
- Update PERSISTENT_CACHE_ENTRY::size after realloc (CVE-2026-33987)
- Update CLEAR_GLYPH_ENTRY::count after alloc (CVE-2026-33985)
- Use winpr_aligned_calloc in persistent cache (CVE-2026-33982)
Resolves: RHEL-159803, RHEL-159659, RHEL-161033, RHEL-161468
Resolves: RHEL-161504, RHEL-161071, RHEL-163653, RHEL-167791, RHEL-162930
* Fri Apr 10 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.6
- Update CLEAR_VBAR_ENTRY size after alloc (CVE-2026-33984)
- Fail progressive_rfx_quant_sub on invalid values (CVE-2026-33983)