Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRDP/FreeRDP.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fleisz <martin.fleisz@thincast.com>2020-07-20 16:38:46 +0300
committerGitHub <noreply@github.com>2020-07-20 16:38:46 +0300
commitd2ba84a6885f57674098fe8e76c5f99d880e580d (patch)
treeb73984700f16ddc32067dbe99bde75bba765357b
parent8f3e7aa3730af14a2b693b3ef0bd093d8f2aef82 (diff)
parent3640d45996b6b1909059d31b4446da6b497458a8 (diff)
Merge pull request #6382 from bmiklautz/release_2202.2.0
FreeRDP security and version 2.2.0 release
-rw-r--r--ChangeLog28
-rw-r--r--channels/rdpgfx/rdpgfx_common.c4
-rw-r--r--libfreerdp/core/orders.c14
-rw-r--r--libfreerdp/core/tpdu.c2
-rw-r--r--libfreerdp/gdi/gfx.c31
5 files changed, 67 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ecea0919..1e98eabe3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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,