diff options
author | Martin Fleisz <martin.fleisz@thincast.com> | 2020-07-20 16:38:46 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-20 16:38:46 +0300 |
commit | d2ba84a6885f57674098fe8e76c5f99d880e580d (patch) | |
tree | b73984700f16ddc32067dbe99bde75bba765357b | |
parent | 8f3e7aa3730af14a2b693b3ef0bd093d8f2aef82 (diff) | |
parent | 3640d45996b6b1909059d31b4446da6b497458a8 (diff) |
Merge pull request #6382 from bmiklautz/release_2202.2.0
FreeRDP security and version 2.2.0 release
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | channels/rdpgfx/rdpgfx_common.c | 4 | ||||
-rw-r--r-- | libfreerdp/core/orders.c | 14 | ||||
-rw-r--r-- | libfreerdp/core/tpdu.c | 2 | ||||
-rw-r--r-- | libfreerdp/gdi/gfx.c | 31 |
5 files changed, 67 insertions, 12 deletions
@@ -1,3 +1,31 @@ +# 2020-07-20 Version 2.2.0 + +Important notes: +* CVE-2020-15103 - Integer overflow due to missing input sanitation in rdpegfx channel + +Noteworty changes: +* fix: memory leak in nsc +* urbdrc + * some fixes and improvements +* build + * use cmake to detect getlogin_r + * improve asan checks/detection +* server/proxy + * new: support for heartbeats + * new: support for rail handshake ex flags + * fix: possible race condition with redirects + +Fixed issues: +* #6263 Sound & mic - filter GSM codec for microphone redirection +* #6335: windows client title length +* #6370 - "Alternate Secondary Drawing Order UNKNOWN" +* #6298 - remoteapp with dialog is disconnecting when it loses focus +* #6299 - v2.1.2: Can't connect to Windows7 + +For a complete and detailed change log since the last release run: +git log 2.1.2..2.2.0 + + # 2020-06-22 Version 2.1.2 Important notes: 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; } diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 4e62ce5ff..74870fae6 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -2623,7 +2623,7 @@ static BOOL update_decompress_brush(wStream* s, BYTE* output, size_t outSize, BY const BYTE* palette = Stream_Pointer(s) + 16; const INT32 bytesPerPixel = ((bpp + 1) / 8); - if (!Stream_SafeSeek(s, 16ULL + 7ULL * bytesPerPixel)) // 64 / 4 + if (Stream_GetRemainingLength(s) < 16 + bytesPerPixel * 4) return FALSE; for (y = 7; y >= 0; y--) @@ -3617,7 +3617,7 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) { BOOL rc = FALSE; - size_t start, end, diff; + size_t start, end, pos, diff; BYTE orderType; UINT16 extraFlags; UINT16 orderLength; @@ -3766,15 +3766,15 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flag WLog_Print(update->log, WLOG_ERROR, "SECONDARY ORDER %s failed", name); } - start += orderLength + 7; - end = Stream_GetPosition(s); - if (start > end) + end = start + orderLength + 7; + pos = Stream_GetPosition(s); + if (pos > end) { WLog_Print(update->log, WLOG_WARN, "SECONDARY_ORDER %s: read %" PRIuz "bytes too much", - name, end - start); + name, pos - end); return FALSE; } - diff = end - start; + diff = end - pos; if (diff > 0) { WLog_Print(update->log, WLOG_DEBUG, diff --git a/libfreerdp/core/tpdu.c b/libfreerdp/core/tpdu.c index 10aa1dfe0..27175887d 100644 --- a/libfreerdp/core/tpdu.c +++ b/libfreerdp/core/tpdu.c @@ -84,7 +84,7 @@ BOOL tpdu_read_header(wStream* s, BYTE* code, BYTE* li, UINT16 tpktlength) if (*li + 4 > tpktlength) { - WLog_ERR(TAG, "tpdu length %" PRIu16 " > tpkt header length %" PRIu16, li, tpktlength); + WLog_ERR(TAG, "tpdu length %" PRIu8 " > tpkt header length %" PRIu16, *li, tpktlength); return FALSE; } 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, |