mirror of https://github.com/FreeRDP/FreeRDP
Merge pull request #6381 from bmiklautz/master_sec_plus_220
FreeRDP security
This commit is contained in:
commit
44e4f4fda0
28
ChangeLog
28
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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -2674,8 +2674,10 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre
|
|||
if (!rc)
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT8(s, cache_brush->cx); /* cx (1 byte) */
|
||||
Stream_Read_UINT8(s, cache_brush->cy); /* cy (1 byte) */
|
||||
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 +2692,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 +2705,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 +3637,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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue