import Oracle_OSS freerdp-3.10.3-12.el10_2.7
This commit is contained in:
parent
5335061a79
commit
3392ca130c
163
core-orders-add-codecID-checks.patch
Normal file
163
core-orders-add-codecID-checks.patch
Normal file
@ -0,0 +1,163 @@
|
||||
From 64649715f9aa691c8435d05cc17ccf468cbb3afa Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Tue, 16 Jun 2026 10:53:16 +0200
|
||||
Subject: [PATCH] [core,orders] add codecID checks
|
||||
|
||||
Abort early if an unsupported/deactivated codecID value is found for a
|
||||
CACHE_BITMAP_V3_ORDER.
|
||||
---
|
||||
libfreerdp/core/orders.c | 94 +++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 82 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c
|
||||
index 6c5f98ab6..c725aa790 100644
|
||||
--- a/libfreerdp/core/orders.c
|
||||
+++ b/libfreerdp/core/orders.c
|
||||
@@ -2446,7 +2446,7 @@ static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* updat
|
||||
if (!cache_bitmap_v2)
|
||||
goto fail;
|
||||
|
||||
- cache_bitmap_v2->cacheId = flags & 0x0003;
|
||||
+ cache_bitmap_v2->cacheId = flags & 0x0007;
|
||||
cache_bitmap_v2->flags = (flags & 0xFF80) >> 7;
|
||||
bitsPerPixelId = (flags & 0x0078) >> 3;
|
||||
cache_bitmap_v2->bitmapBpp = get_cbr2_bpp(bitsPerPixelId, &rc);
|
||||
@@ -2620,27 +2620,43 @@ static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* updat
|
||||
UINT16 flags)
|
||||
{
|
||||
BOOL rc = 0;
|
||||
- BYTE bitsPerPixelId = 0;
|
||||
- BITMAP_DATA_EX* bitmapData = NULL;
|
||||
UINT32 new_len = 0;
|
||||
BYTE* new_data = NULL;
|
||||
- CACHE_BITMAP_V3_ORDER* cache_bitmap_v3 = NULL;
|
||||
rdp_update_internal* up = update_cast(update);
|
||||
|
||||
if (!update || !s)
|
||||
return NULL;
|
||||
|
||||
- cache_bitmap_v3 = calloc(1, sizeof(CACHE_BITMAP_V3_ORDER));
|
||||
+ WINPR_ASSERT(update->context);
|
||||
+
|
||||
+ const rdpSettings* settings = update->context->settings;
|
||||
+ WINPR_ASSERT(settings);
|
||||
+
|
||||
+ if (!freerdp_settings_get_bool(settings, FreeRDP_BitmapCacheV3Enabled))
|
||||
+ {
|
||||
+ WLog_Print(up->log, WLOG_ERROR, "BitmapCacheV3 not enabled for this connection, aborting");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ CACHE_BITMAP_V3_ORDER* cache_bitmap_v3 = calloc(1, sizeof(CACHE_BITMAP_V3_ORDER));
|
||||
|
||||
if (!cache_bitmap_v3)
|
||||
goto fail;
|
||||
|
||||
- cache_bitmap_v3->cacheId = flags & 0x00000003;
|
||||
- cache_bitmap_v3->flags = (flags & 0x0000FF80) >> 7;
|
||||
- bitsPerPixelId = (flags & 0x00000078) >> 3;
|
||||
- cache_bitmap_v3->bpp = get_cbr2_bpp(bitsPerPixelId, &rc);
|
||||
- if (!rc)
|
||||
+ cache_bitmap_v3->cacheId = flags & 0x00000007;
|
||||
+ const UINT32 NumCellCaches =
|
||||
+ freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells);
|
||||
+ if (cache_bitmap_v3->cacheId >= NumCellCaches)
|
||||
+ {
|
||||
+ WLog_Print(up->log, WLOG_ERROR,
|
||||
+ "BitmapCacheV3::cacheId %" PRIu32 " > NumCellCaches %" PRIu32,
|
||||
+ cache_bitmap_v3->cacheId, NumCellCaches);
|
||||
goto fail;
|
||||
+ }
|
||||
+ cache_bitmap_v3->flags = (flags >> 7) & 0x000001FF;
|
||||
+
|
||||
+ const BYTE bitsPerPixelId = (flags >> 3) & 0x000000F;
|
||||
+ cache_bitmap_v3->bpp = get_cbr2_bpp(bitsPerPixelId, &rc);
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 21))
|
||||
goto fail;
|
||||
@@ -2648,7 +2664,20 @@ static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* updat
|
||||
Stream_Read_UINT16(s, cache_bitmap_v3->cacheIndex); /* cacheIndex (2 bytes) */
|
||||
Stream_Read_UINT32(s, cache_bitmap_v3->key1); /* key1 (4 bytes) */
|
||||
Stream_Read_UINT32(s, cache_bitmap_v3->key2); /* key2 (4 bytes) */
|
||||
- bitmapData = &cache_bitmap_v3->bitmapData;
|
||||
+
|
||||
+ if ((cache_bitmap_v3->flags & CBR3_DO_NOT_CACHE) != 0)
|
||||
+ {
|
||||
+ rdpCache* cache = update->context->cache;
|
||||
+ WINPR_ASSERT(cache);
|
||||
+
|
||||
+ if (cache_bitmap_v3->cacheId >= cache->bitmap->maxCells)
|
||||
+ goto fail;
|
||||
+
|
||||
+ BITMAP_V2_CELL* cell = &cache->bitmap->cells[cache_bitmap_v3->cacheId];
|
||||
+ cache_bitmap_v3->cacheIndex = cell->number;
|
||||
+ }
|
||||
+
|
||||
+ BITMAP_DATA_EX* bitmapData = &cache_bitmap_v3->bitmapData;
|
||||
Stream_Read_UINT8(s, bitmapData->bpp);
|
||||
|
||||
if ((bitmapData->bpp < 1) || (bitmapData->bpp > 32))
|
||||
@@ -2657,6 +2686,13 @@ static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* updat
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ /* [MS-RDPEGDI] 2.2.2.2.1.2.8 Cache Bitmap - Revision 3 (CACHE_BITMAP_REV3_ORDER)
|
||||
+ * tells this should not be 0, but it is for some windows versions.
|
||||
+ * fall back to setting color depth from bitmapData
|
||||
+ */
|
||||
+ if (!rc)
|
||||
+ cache_bitmap_v3->bpp = bitmapData->bpp;
|
||||
+
|
||||
Stream_Seek_UINT8(s); /* reserved1 (1 byte) */
|
||||
Stream_Seek_UINT8(s); /* reserved2 (1 byte) */
|
||||
Stream_Read_UINT8(s, bitmapData->codecID); /* codecID (1 byte) */
|
||||
@@ -2664,6 +2700,40 @@ static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* updat
|
||||
Stream_Read_UINT16(s, bitmapData->height); /* height (2 bytes) */
|
||||
Stream_Read_UINT32(s, new_len); /* length (4 bytes) */
|
||||
|
||||
+ switch (bitmapData->codecID)
|
||||
+ {
|
||||
+ case RDP_CODEC_ID_IMAGE_REMOTEFX:
|
||||
+ if (!freerdp_settings_get_bool(settings, FreeRDP_RemoteFxImageCodec))
|
||||
+ {
|
||||
+ WLog_Print(up->log, WLOG_ERROR,
|
||||
+ "codecID RDP_CODEC_ID_IMAGE_REMOTEFX not enabled for this "
|
||||
+ "connection, aborting");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ break;
|
||||
+ case RDP_CODEC_ID_REMOTEFX:
|
||||
+ if (!freerdp_settings_get_bool(settings, FreeRDP_RemoteFxCodec))
|
||||
+ {
|
||||
+ WLog_ERR(TAG,
|
||||
+ "codecID RDP_CODEC_ID_REMOTEFX not enabled for this connection, aborting");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ break;
|
||||
+ case RDP_CODEC_ID_NSCODEC:
|
||||
+ if (!freerdp_settings_get_bool(settings, FreeRDP_NSCodec))
|
||||
+ {
|
||||
+ WLog_ERR(TAG,
|
||||
+ "codecID RDP_CODEC_ID_NSCODEC not enabled for this connection, aborting");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ break;
|
||||
+ case RDP_CODEC_ID_NONE:
|
||||
+ break;
|
||||
+ default:
|
||||
+ WLog_ERR(TAG, "Unsupported codecID 0x%08" PRIx32, bitmapData->codecID);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if ((new_len == 0) || (!Stream_CheckAndLogRequiredLength(TAG, s, new_len)))
|
||||
goto fail;
|
||||
|
||||
@@ -2706,7 +2776,7 @@ BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache
|
||||
bitsPerPixelId = get_bpp_bmf(cache_bitmap_v3->bpp, &rc);
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
- *flags = (cache_bitmap_v3->cacheId & 0x00000003) |
|
||||
+ *flags = (cache_bitmap_v3->cacheId & 0x00000007) |
|
||||
((cache_bitmap_v3->flags << 7) & 0x0000FF80) | ((bitsPerPixelId << 3) & 0x00000078);
|
||||
Stream_Write_UINT16(s,
|
||||
get_checked_uint16(cache_bitmap_v3->cacheIndex)); /* cacheIndex (2 bytes) */
|
||||
14
freerdp.spec
14
freerdp.spec
@ -30,7 +30,7 @@
|
||||
Name: freerdp
|
||||
Epoch: 2
|
||||
Version: 3.10.3
|
||||
Release: 12%{?dist}.6
|
||||
Release: 12%{?dist}.7
|
||||
Summary: Free implementation of the Remote Desktop Protocol (RDP)
|
||||
|
||||
# The effective license is Apache-2.0 but:
|
||||
@ -270,6 +270,13 @@ Patch: channels-cliprdr-abort-on-duplicate-caps.patch
|
||||
Patch: channels-rdpear-fix-ndr_read-checks.patch
|
||||
Patch: channels-rdpear-disable-ndr-pointer-aliasing.patch
|
||||
|
||||
# CVE-2026-55827
|
||||
# https://github.com/FreeRDP/FreeRDP/pull/12899
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/7bbb52a193deed5943a041c9859db7ee036044a4
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/3c4ae49f38aa0ea9b073025eb468131375e518ff
|
||||
Patch: core-orders-add-codecID-checks.patch
|
||||
Patch: gdi-graphics-fix-gdi_Bitmap_Decompress.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: alsa-lib-devel
|
||||
@ -593,6 +600,11 @@ find %{buildroot} -name "*.a" -delete
|
||||
%{_libdir}/pkgconfig/winpr-tools3.pc
|
||||
|
||||
%changelog
|
||||
* Sat Jul 11 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2:3.10.3-12.7
|
||||
- Add codecID checks for CACHE_BITMAP_V3_ORDER (CVE-2026-55827)
|
||||
- Fix boundary checks in gdi_Bitmap_Decompress (CVE-2026-55827)
|
||||
Resolves: RHEL-194327
|
||||
|
||||
* Mon Jun 29 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-12.6
|
||||
- Backport several CVE fixes (CVE-2026-40033, CVE-2026-44420, CVE-2026-44421,
|
||||
CVE-2026-44422, CVE-2026-45700)
|
||||
|
||||
185
gdi-graphics-fix-gdi_Bitmap_Decompress.patch
Normal file
185
gdi-graphics-fix-gdi_Bitmap_Decompress.patch
Normal file
@ -0,0 +1,185 @@
|
||||
From 053e4d7a9984d607b086816f1732bcc2619677c8 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Tue, 16 Jun 2026 10:59:40 +0200
|
||||
Subject: [PATCH] [gdi,graphics] fix gdi_Bitmap_Decompress
|
||||
|
||||
* Properly check boundaries when decoding data
|
||||
---
|
||||
libfreerdp/gdi/graphics.c | 131 +++++++++++++++++++++++---------------
|
||||
1 file changed, 78 insertions(+), 53 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c
|
||||
index eec5cd6b9..6f82c2eda 100644
|
||||
--- a/libfreerdp/gdi/graphics.c
|
||||
+++ b/libfreerdp/gdi/graphics.c
|
||||
@@ -130,26 +130,55 @@ static BOOL gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
|
||||
gdi_bitmap->hdc, 0, 0, GDI_SRCCOPY, &context->gdi->palette);
|
||||
}
|
||||
|
||||
+static BOOL gdi_Bitmap_Rfx(rdpContext* context, rdpBitmap* bitmap, const BYTE* pSrcData,
|
||||
+ UINT32 SrcSize)
|
||||
+{
|
||||
+ WINPR_ASSERT(context);
|
||||
+ WINPR_ASSERT(bitmap);
|
||||
+ WINPR_ASSERT(pSrcData || (SrcSize == 0));
|
||||
+
|
||||
+ REGION16 invalidRegion;
|
||||
+ region16_init(&invalidRegion);
|
||||
+
|
||||
+ const UINT32 stride = bitmap->width * FreeRDPGetBytesPerPixel(bitmap->format);
|
||||
+
|
||||
+ const BOOL rc =
|
||||
+ rfx_process_message(context->codecs->rfx, pSrcData, SrcSize, bitmap->left, bitmap->top,
|
||||
+ bitmap->data, bitmap->format, stride, bitmap->height, &invalidRegion);
|
||||
+ region16_uninit(&invalidRegion);
|
||||
+
|
||||
+ if (!rc)
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "rfx_process_message failed");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, const BYTE* pSrcData,
|
||||
UINT32 DstWidth, UINT32 DstHeight, UINT32 bpp, UINT32 length,
|
||||
BOOL compressed, UINT32 codecId)
|
||||
{
|
||||
+ WINPR_ASSERT(context);
|
||||
+ WINPR_ASSERT(bitmap);
|
||||
+
|
||||
UINT32 SrcSize = length;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
- UINT32 size = DstWidth * DstHeight;
|
||||
+ WINPR_ASSERT(gdi);
|
||||
+
|
||||
bitmap->compressed = FALSE;
|
||||
bitmap->format = gdi->dstFormat;
|
||||
|
||||
if ((FreeRDPGetBytesPerPixel(bitmap->format) == 0) || (DstWidth == 0) || (DstHeight == 0) ||
|
||||
(DstWidth > UINT32_MAX / DstHeight) ||
|
||||
- (size > (UINT32_MAX / FreeRDPGetBytesPerPixel(bitmap->format))))
|
||||
+ ((DstWidth * DstHeight) > (UINT32_MAX / FreeRDPGetBytesPerPixel(bitmap->format))))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid input data");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- size *= FreeRDPGetBytesPerPixel(bitmap->format);
|
||||
- bitmap->length = size;
|
||||
+ const UINT32 stride = DstWidth * FreeRDPGetBytesPerPixel(bitmap->format);
|
||||
+ bitmap->length = stride * DstHeight;
|
||||
bitmap->data = (BYTE*)winpr_aligned_malloc(bitmap->length, 16);
|
||||
|
||||
if (!bitmap->data)
|
||||
@@ -157,57 +186,53 @@ static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, const
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
- if ((codecId == RDP_CODEC_ID_REMOTEFX) || (codecId == RDP_CODEC_ID_IMAGE_REMOTEFX))
|
||||
+ WINPR_ASSERT(context->codecs);
|
||||
+ switch (codecId)
|
||||
{
|
||||
- REGION16 invalidRegion;
|
||||
- region16_init(&invalidRegion);
|
||||
-
|
||||
- if (!rfx_process_message(context->codecs->rfx, pSrcData, SrcSize, bitmap->left,
|
||||
- bitmap->top, bitmap->data, bitmap->format, gdi->stride,
|
||||
- gdi->height, &invalidRegion))
|
||||
+ case RDP_CODEC_ID_REMOTEFX:
|
||||
+ case RDP_CODEC_ID_IMAGE_REMOTEFX:
|
||||
+ if (!gdi_Bitmap_Rfx(context, bitmap, pSrcData, SrcSize))
|
||||
+ return FALSE;
|
||||
+ break;
|
||||
+ case RDP_CODEC_ID_NSCODEC:
|
||||
{
|
||||
- WLog_ERR(TAG, "rfx_process_message failed");
|
||||
- return FALSE;
|
||||
- }
|
||||
- }
|
||||
- else if (codecId == RDP_CODEC_ID_NSCODEC)
|
||||
- {
|
||||
- const int status = nsc_process_message(
|
||||
- context->codecs->nsc, 32, DstWidth, DstHeight, pSrcData, SrcSize, bitmap->data,
|
||||
- bitmap->format, 0, 0, 0, DstWidth, DstHeight, FREERDP_FLIP_VERTICAL);
|
||||
-
|
||||
- if (status < 1)
|
||||
- {
|
||||
- WLog_ERR(TAG, "nsc_process_message failed");
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- return freerdp_image_copy_no_overlap(bitmap->data, bitmap->format, 0, 0, 0, DstWidth,
|
||||
- DstHeight, pSrcData, PIXEL_FORMAT_XRGB32, 0, 0, 0,
|
||||
- &gdi->palette, FREERDP_FLIP_VERTICAL);
|
||||
- }
|
||||
- else if (bpp < 32)
|
||||
- {
|
||||
- if (!interleaved_decompress(context->codecs->interleaved, pSrcData, SrcSize, DstWidth,
|
||||
- DstHeight, bpp, bitmap->data, bitmap->format, 0, 0, 0,
|
||||
- DstWidth, DstHeight, &gdi->palette))
|
||||
- {
|
||||
- WLog_ERR(TAG, "interleaved_decompress failed");
|
||||
- return FALSE;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- const BOOL fidelity =
|
||||
- freerdp_settings_get_bool(context->settings, FreeRDP_DrawAllowDynamicColorFidelity);
|
||||
- freerdp_planar_switch_bgr(context->codecs->planar, fidelity);
|
||||
- if (!planar_decompress(context->codecs->planar, pSrcData, SrcSize, DstWidth, DstHeight,
|
||||
- bitmap->data, bitmap->format, 0, 0, 0, DstWidth, DstHeight,
|
||||
- TRUE))
|
||||
- {
|
||||
- WLog_ERR(TAG, "planar_decompress failed");
|
||||
- return FALSE;
|
||||
+ const int status = nsc_process_message(
|
||||
+ context->codecs->nsc, 32, DstWidth, DstHeight, pSrcData, SrcSize, bitmap->data,
|
||||
+ bitmap->format, stride, 0, 0, DstWidth, DstHeight, FREERDP_FLIP_VERTICAL);
|
||||
+
|
||||
+ if (status < 1)
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "nsc_process_message failed");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
}
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (bpp < 32)
|
||||
+ {
|
||||
+ if (!interleaved_decompress(context->codecs->interleaved, pSrcData, SrcSize,
|
||||
+ DstWidth, DstHeight, bpp, bitmap->data,
|
||||
+ bitmap->format, stride, 0, 0, DstWidth, DstHeight,
|
||||
+ &gdi->palette))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "interleaved_decompress failed");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ const BOOL fidelity = freerdp_settings_get_bool(
|
||||
+ context->settings, FreeRDP_DrawAllowDynamicColorFidelity);
|
||||
+ freerdp_planar_switch_bgr(context->codecs->planar, fidelity);
|
||||
+ if (!planar_decompress(
|
||||
+ context->codecs->planar, pSrcData, SrcSize, DstWidth, DstHeight,
|
||||
+ bitmap->data, bitmap->format, stride, 0, 0, DstWidth, DstHeight, TRUE))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "planar_decompress failed");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -230,7 +255,7 @@ static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, const
|
||||
}
|
||||
}
|
||||
|
||||
- if (!freerdp_image_copy_no_overlap(bitmap->data, bitmap->format, 0, 0, 0, DstWidth,
|
||||
+ if (!freerdp_image_copy_no_overlap(bitmap->data, bitmap->format, stride, 0, 0, DstWidth,
|
||||
DstHeight, pSrcData, SrcFormat, 0, 0, 0, &gdi->palette,
|
||||
FREERDP_FLIP_VERTICAL))
|
||||
{
|
||||
Loading…
Reference in New Issue
Block a user