diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index b9b5e8fcf..b471bce18 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -1881,6 +1881,13 @@ static BOOL update_read_fast_glyph_order(wStream* s, const ORDER_INFO* orderInfo !update_read_2byte_unsigned(&sub, &glyph->cy)) return FALSE; + if ((glyph->cx == 0) || (glyph->cy == 0)) + { + WLog_ERR(TAG, "GLYPH_DATA_V2::cx=%" PRIu32 ", GLYPH_DATA_V2::cy=%" PRIu32, + glyph->cx, glyph->cy); + return FALSE; + } + glyph->cb = Stream_GetRemainingLength(&sub); if (glyph->cb > 0) { @@ -2868,6 +2875,13 @@ update_read_create_offscreen_bitmap_order(wStream* s, Stream_Read_UINT16(s, create_offscreen_bitmap->cy); /* cy (2 bytes) */ deleteList = &(create_offscreen_bitmap->deleteList); + if ((create_offscreen_bitmap->cx == 0) || (create_offscreen_bitmap->cy == 0)) + { + WLog_ERR(TAG, "Invalid OFFSCREEN_DELETE_LIST: cx=%" PRIu16 ", cy=%" PRIu16, + create_offscreen_bitmap->cx, create_offscreen_bitmap->cy); + return FALSE; + } + if (deleteListPresent) { UINT32 i; diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c index 3bdfacf24..988f93787 100644 --- a/libfreerdp/core/surface.c +++ b/libfreerdp/core/surface.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include @@ -60,6 +62,13 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp) Stream_Read_UINT16(s, bmp->height); Stream_Read_UINT32(s, bmp->bitmapDataLength); + if ((bmp->width == 0) || (bmp->height == 0)) + { + WLog_ERR(TAG, "invalid size value width=%" PRIu16 ", height=%" PRIu16, bmp->width, + bmp->height); + return FALSE; + } + if ((bmp->bpp < 1) || (bmp->bpp > 32)) { WLog_ERR(TAG, "invalid bpp value %" PRIu32 "", bmp->bpp); @@ -76,6 +85,39 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp) return Stream_SafeSeek(s, bmp->bitmapDataLength); } +static BOOL update_recv_surfcmd_is_rect_valid(const rdpContext* context, + const SURFACE_BITS_COMMAND* cmd) +{ + WINPR_ASSERT(context); + WINPR_ASSERT(context->settings); + WINPR_ASSERT(cmd); + + /* We need a rectangle with left/top being smaller than right/bottom. + * Also do not allow empty rectangles. */ + if ((cmd->destTop >= cmd->destBottom) || (cmd->destLeft >= cmd->destRight)) + { + WLog_WARN(TAG, + "Empty surface bits command rectangle: %" PRIu16 "x%" PRIu16 "-%" PRIu16 + "x%" PRIu16, + cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom); + return FALSE; + } + + /* The rectangle needs to fit into our session size */ + if ((cmd->destRight > context->settings->DesktopWidth) || + (cmd->destBottom > context->settings->DesktopHeight)) + { + WLog_WARN(TAG, + "Invalid surface bits command rectangle: %" PRIu16 "x%" PRIu16 "-%" PRIu16 + "x%" PRIu16 " does not fit %" PRIu32 "x%" PRIu32, + cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom, + context->settings->DesktopWidth, context->settings->DesktopHeight); + return FALSE; + } + + return TRUE; +} + static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT16 cmdType) { SURFACE_BITS_COMMAND cmd = { 0 }; @@ -89,6 +131,9 @@ static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT Stream_Read_UINT16(s, cmd.destRight); Stream_Read_UINT16(s, cmd.destBottom); + if (!update_recv_surfcmd_is_rect_valid(update->context, &cmd)) + goto fail; + if (!update_recv_surfcmd_bitmap_ex(s, &cmd.bmp)) goto fail; diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index cc65c40bb..076e7bb2a 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -99,6 +99,13 @@ static BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* Stream_Read_UINT16(s, bitmapData->flags); Stream_Read_UINT16(s, bitmapData->bitmapLength); + if ((bitmapData->width == 0) || (bitmapData->height == 0)) + { + WLog_ERR(TAG, "Invalid BITMAP_DATA: width=%" PRIu16 ", height=%" PRIu16, bitmapData->width, + bitmapData->height); + return FALSE; + } + if (bitmapData->flags & BITMAP_COMPRESSION) { if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR))