Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:Update
freerdp.24943
freerdp-CVE-2020-15103.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File freerdp-CVE-2020-15103.patch of Package freerdp.24943
From efdc99528f6fb6d56537a5420bfa8e735219eba0 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz <bernhard.miklautz@thincast.com> Date: Wed, 15 Jul 2020 18:04:02 +0200 Subject: [PATCH 1/3] new [orders]: BMF_24BPP support and some comments * cached brush orders missed the BMF_24BPP documented case ([MS-RDPEGDI] 2.2.2.2.1.2.7) * add some comments on secondary (brush) order details --- libfreerdp/core/orders.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 74870fae6..1608b7ccb 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -2676,6 +2676,7 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre Stream_Read_UINT8(s, cache_brush->cx); /* cx (1 byte) */ Stream_Read_UINT8(s, cache_brush->cy); /* cy (1 byte) */ + /* according to Section 2.2.2.2.1.2.7 errata the windows implementation sets this filed is set to 0x00 */ Stream_Read_UINT8(s, cache_brush->style); /* style (1 byte) */ Stream_Read_UINT8(s, cache_brush->length); /* iBytes (1 byte) */ @@ -2690,14 +2691,12 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre goto fail; } - /* rows are encoded in reverse order */ if (Stream_GetRemainingLength(s) < 8) goto fail; + /* rows are encoded in reverse order */ for (i = 7; i >= 0; i--) - { Stream_Read_UINT8(s, cache_brush->data[i]); - } } else { @@ -2705,6 +2704,8 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre compressed = TRUE; else if ((iBitmapFormat == BMF_16BPP) && (cache_brush->length == 24)) compressed = TRUE; + else if ((iBitmapFormat == BMF_24BPP) && (cache_brush->length == 28)) + compressed = TRUE; else if ((iBitmapFormat == BMF_32BPP) && (cache_brush->length == 32)) compressed = TRUE; @@ -3635,6 +3636,10 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flag Stream_Read_UINT16(s, orderLength); /* orderLength (2 bytes) */ Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ Stream_Read_UINT8(s, orderType); /* orderType (1 byte) */ + /* + * According to [MS-RDPEGDI] 2.2.2.2.1.2.1.1 the order length must be increased by 13 bytes + * including the header. As we already read the header 7 left + */ if (Stream_GetRemainingLength(s) < orderLength + 7U) { WLog_Print(update->log, WLOG_ERROR, "Stream_GetRemainingLength(s) %" PRIuz " < %" PRIu16, -- 2.28.0 From 40393700642ad38437982e8a3afc34ff33ccf28e Mon Sep 17 00:00:00 2001 From: akallabeth <akallabeth@posteo.net> Date: Fri, 3 Jul 2020 10:26:38 +0200 Subject: [PATCH 2/3] Fixed input sanitation in rdpgfx_recv_solid_fill_pdu The input rectangle must be checked for plausibility. Thanks to Sunglin and HuanGMz of the Knownsec 404 security team and pangzi of pwnzen --- channels/rdpgfx/rdpgfx_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/channels/rdpgfx/rdpgfx_common.c b/channels/rdpgfx/rdpgfx_common.c index 090aa50ab..e0a50a606 100644 --- a/channels/rdpgfx/rdpgfx_common.c +++ b/channels/rdpgfx/rdpgfx_common.c @@ -182,6 +182,10 @@ UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16) Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */ Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */ Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */ + if (rect16->left >= rect16->right) + return ERROR_INVALID_DATA; + if (rect16->top >= rect16->bottom) + return ERROR_INVALID_DATA; return CHANNEL_RC_OK; } -- 2.28.0 From e08a23f93136f59a52651f66d064b8d4303872e1 Mon Sep 17 00:00:00 2001 From: akallabeth <akallabeth@posteo.net> Date: Fri, 3 Jul 2020 10:29:13 +0200 Subject: [PATCH 3/3] Fixed missing input sanitation for GFX surfaces. Thanks to Sunglin and HuanGMz of the Knownsec 404 security team and pangzi of pwnzen --- libfreerdp/gdi/gfx.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c index e3a6e66e0..f368165b6 100644 --- a/libfreerdp/gdi/gfx.c +++ b/libfreerdp/gdi/gfx.c @@ -31,6 +31,17 @@ #define TAG FREERDP_TAG("gdi") +static BOOL is_rect_valid(const RECTANGLE_16* rect, size_t width, size_t height) +{ + if (!rect) + return FALSE; + if ((rect->left > rect->right) || (rect->right > width)) + return FALSE; + if ((rect->top > rect->bottom) || (rect->bottom > height)) + return FALSE; + return TRUE; +} + static DWORD gfx_align_scanline(DWORD widthInBytes, DWORD alignment) { const UINT32 align = alignment; @@ -1114,7 +1125,6 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, BOOL sameSurface; UINT32 nWidth, nHeight; const RECTANGLE_16* rectSrc; - RDPGFX_POINT16* destPt; RECTANGLE_16 invalidRect; gdiGfxSurface* surfaceSrc; gdiGfxSurface* surfaceDst; @@ -1134,12 +1144,18 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, if (!surfaceSrc || !surfaceDst) goto fail; + if (!is_rect_valid(rectSrc, surfaceSrc->width, surfaceSrc->height)) + goto fail; + nWidth = rectSrc->right - rectSrc->left; nHeight = rectSrc->bottom - rectSrc->top; for (index = 0; index < surfaceToSurface->destPtsCount; index++) { - destPt = &surfaceToSurface->destPts[index]; + const RDPGFX_POINT16* destPt = &surfaceToSurface->destPts[index]; + const RECTANGLE_16 rect = { destPt->x, destPt->y, destPt->x + nWidth, destPt->y + nHeight }; + if (!is_rect_valid(&rect, surfaceDst->width, surfaceDst->height)) + goto fail; if (!freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline, destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, @@ -1192,6 +1208,9 @@ static UINT gdi_SurfaceToCache(RdpgfxClientContext* context, if (!surface) goto fail; + if (!is_rect_valid(rect, surface->width, surface->height)) + goto fail; + cacheEntry = (gdiGfxCacheEntry*)calloc(1, sizeof(gdiGfxCacheEntry)); if (!cacheEntry) @@ -1234,7 +1253,6 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context, { UINT status = ERROR_INTERNAL_ERROR; UINT16 index; - RDPGFX_POINT16* destPt; gdiGfxSurface* surface; gdiGfxCacheEntry* cacheEntry; RECTANGLE_16 invalidRect; @@ -1248,7 +1266,12 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context, for (index = 0; index < cacheToSurface->destPtsCount; index++) { - destPt = &cacheToSurface->destPts[index]; + const RDPGFX_POINT16* destPt = &cacheToSurface->destPts[index]; + const RECTANGLE_16 rect = { destPt->x, destPt->y, destPt->x + cacheEntry->width, + destPt->y + cacheEntry->height }; + + if (!is_rect_valid(&rect, surface->width, surface->height)) + goto fail; if (!freerdp_image_copy(surface->data, surface->format, surface->scanline, destPt->x, destPt->y, cacheEntry->width, cacheEntry->height, cacheEntry->data, -- 2.28.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor