From 3e3c0f19427ec2c847d53a07a7cdda1d015ceaee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 3 Nov 2013 13:29:48 -0500 Subject: [PATCH] libfreerdp-core: fix potential asynchronous queuing memory problems for primary drawing orders --- libfreerdp/core/message.c | 30 +++++++++++++++++++++++++++++- libfreerdp/core/orders.c | 2 ++ libfreerdp/core/transport.c | 16 ++++++++++------ libfreerdp/core/update.c | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index 196092af5..b810fa1ad 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -217,6 +217,8 @@ static void update_message_PatBlt(rdpContext* context, PATBLT_ORDER* patBlt) wParam = (PATBLT_ORDER*) malloc(sizeof(PATBLT_ORDER)); CopyMemory(wParam, patBlt, sizeof(PATBLT_ORDER)); + wParam->brush.data = (BYTE*) wParam->brush.p8x8; + MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, PatBlt), (void*) wParam, NULL); } @@ -272,6 +274,8 @@ static void update_message_MultiPatBlt(rdpContext* context, MULTI_PATBLT_ORDER* wParam = (MULTI_PATBLT_ORDER*) malloc(sizeof(MULTI_PATBLT_ORDER)); CopyMemory(wParam, multiPatBlt, sizeof(MULTI_PATBLT_ORDER)); + wParam->brush.data = (BYTE*) wParam->brush.p8x8; + MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, MultiPatBlt), (void*) wParam, NULL); } @@ -354,6 +358,8 @@ static void update_message_Mem3Blt(rdpContext* context, MEM3BLT_ORDER* mem3Blt) wParam = (MEM3BLT_ORDER*) malloc(sizeof(MEM3BLT_ORDER)); CopyMemory(wParam, mem3Blt, sizeof(MEM3BLT_ORDER)); + wParam->brush.data = (BYTE*) wParam->brush.p8x8; + MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, Mem3Blt), (void*) wParam, NULL); } @@ -376,6 +382,8 @@ static void update_message_GlyphIndex(rdpContext* context, GLYPH_INDEX_ORDER* gl wParam = (GLYPH_INDEX_ORDER*) malloc(sizeof(GLYPH_INDEX_ORDER)); CopyMemory(wParam, glyphIndex, sizeof(GLYPH_INDEX_ORDER)); + wParam->brush.data = (BYTE*) wParam->brush.p8x8; + MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, GlyphIndex), (void*) wParam, NULL); } @@ -398,6 +406,16 @@ static void update_message_FastGlyph(rdpContext* context, FAST_GLYPH_ORDER* fast wParam = (FAST_GLYPH_ORDER*) malloc(sizeof(FAST_GLYPH_ORDER)); CopyMemory(wParam, fastGlyph, sizeof(FAST_GLYPH_ORDER)); + if (wParam->cbData > 1) + { + wParam->glyphData.aj = (BYTE*) malloc(fastGlyph->glyphData.cb); + CopyMemory(wParam->glyphData.aj, fastGlyph->glyphData.aj, fastGlyph->glyphData.cb); + } + else + { + wParam->glyphData.aj = NULL; + } + MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, FastGlyph), (void*) wParam, NULL); } @@ -426,6 +444,8 @@ static void update_message_PolygonCB(rdpContext* context, POLYGON_CB_ORDER* poly wParam->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * wParam->numPoints); CopyMemory(wParam->points, polygonCB, sizeof(DELTA_POINT) * wParam->numPoints); + wParam->brush.data = (BYTE*) wParam->brush.p8x8; + MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, PolygonCB), (void*) wParam, NULL); } @@ -448,6 +468,8 @@ static void update_message_EllipseCB(rdpContext* context, ELLIPSE_CB_ORDER* elli wParam = (ELLIPSE_CB_ORDER*) malloc(sizeof(ELLIPSE_CB_ORDER)); CopyMemory(wParam, ellipseCB, sizeof(ELLIPSE_CB_ORDER)); + wParam->brush.data = (BYTE*) wParam->brush.p8x8; + MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, EllipseCB), (void*) wParam, NULL); } @@ -994,6 +1016,7 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in #endif } + free(wParam->rectangles); free(wParam); } break; @@ -1159,7 +1182,12 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* case PrimaryUpdate_FastGlyph: IFCALL(proxy->FastGlyph, msg->context, (FAST_GLYPH_ORDER*) msg->wParam); - free(msg->wParam); + { + FAST_GLYPH_ORDER* wParam = (FAST_GLYPH_ORDER*) msg->wParam; + if (wParam->glyphData.aj) + free(wParam->glyphData.aj); + free(wParam); + } break; case PrimaryUpdate_PolygonSC: diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 6fb547d9d..5836da631 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -1356,6 +1356,7 @@ BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* m memblt->colorIndex = (memblt->cacheId >> 8); memblt->cacheId = (memblt->cacheId & 0xFF); + memblt->bitmap = NULL; return TRUE; } @@ -1422,6 +1423,7 @@ BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* ORDER_FIELD_UINT16(16, mem3blt->cacheIndex); mem3blt->colorIndex = (mem3blt->cacheId >> 8); mem3blt->cacheId = (mem3blt->cacheId & 0xFF); + mem3blt->bitmap = NULL; return TRUE; } diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 0d086e0d0..f6fdf2d56 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -88,11 +88,17 @@ BOOL transport_disconnect(rdpTransport* transport) if (transport->async) { - SetEvent(transport->stopEvent); - WaitForSingleObject(transport->thread, INFINITE); + if (transport->stopEvent) + { + SetEvent(transport->stopEvent); + WaitForSingleObject(transport->thread, INFINITE); - CloseHandle(transport->thread); - CloseHandle(transport->stopEvent); + CloseHandle(transport->thread); + CloseHandle(transport->stopEvent); + + transport->thread = NULL; + transport->stopEvent = NULL; + } } return status; @@ -1035,8 +1041,6 @@ void transport_free(rdpTransport* transport) { if (transport) { - SetEvent(transport->stopEvent); - if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 14d6bb1f9..49077aec6 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -1612,7 +1612,7 @@ void update_free(rdpUpdate* update) free(update->primary->polyline.points); free(update->primary->polygon_sc.points); - if (NULL != update->primary->fast_glyph.glyphData.aj) + if (update->primary->fast_glyph.glyphData.aj) free(update->primary->fast_glyph.glyphData.aj); free(update->primary);