From b4e542ba4606ab62bf4733f19e717e0ab75cf519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 1 Feb 2012 18:42:20 -0500 Subject: [PATCH] libfreerdp-core: fix multiple memory leaks detected by valgrind --- channels/cliprdr/cliprdr_format.c | 1 + channels/cliprdr/cliprdr_main.c | 5 ++++ client/X11/xfreerdp.c | 31 +++++++---------------- include/freerdp/codec/color.h | 3 +++ include/freerdp/gdi/dc.h | 1 + libfreerdp-cache/bitmap.c | 2 +- libfreerdp-cache/brush.c | 26 +++++++++++++++++-- libfreerdp-cache/glyph.c | 7 ++++++ libfreerdp-cache/pointer.c | 12 +-------- libfreerdp-codec/color.c | 23 +++++++++++++++++ libfreerdp-core/certificate.c | 5 ++++ libfreerdp-core/connection.c | 10 ++++---- libfreerdp-core/credssp.c | 3 +++ libfreerdp-core/freerdp.c | 6 ++++- libfreerdp-core/graphics.c | 12 +++++++++ libfreerdp-core/license.c | 1 + libfreerdp-core/mppc.c | 15 ++++++++--- libfreerdp-core/settings.c | 3 +++ libfreerdp-gdi/dc.c | 42 +++++++++++++++++++++++++++++-- 19 files changed, 161 insertions(+), 47 deletions(-) diff --git a/channels/cliprdr/cliprdr_format.c b/channels/cliprdr/cliprdr_format.c index 4cf0ae26c..c00503c9b 100644 --- a/channels/cliprdr/cliprdr_format.c +++ b/channels/cliprdr/cliprdr_format.c @@ -91,6 +91,7 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS s = cliprdr_packet_new(CB_FORMAT_LIST, 0, stream_get_size(body)); stream_write(s, stream_get_head(body), stream_get_size(body)); + stream_free(body); } cliprdr_packet_send(cliprdr, s); diff --git a/channels/cliprdr/cliprdr_main.c b/channels/cliprdr/cliprdr_main.c index 6a2fc99b3..a2f5a79a2 100644 --- a/channels/cliprdr/cliprdr_main.c +++ b/channels/cliprdr/cliprdr_main.c @@ -263,6 +263,11 @@ static void cliprdr_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) static void cliprdr_process_terminate(rdpSvcPlugin* plugin) { + cliprdrPlugin* cliprdr_plugin = (cliprdrPlugin*) plugin; + + if (cliprdr_plugin->uniconv != NULL) + freerdp_uniconv_free(cliprdr_plugin->uniconv); + xfree(plugin); } diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 0cc6eba33..1d14774bc 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -547,11 +547,7 @@ boolean xf_pre_connect(freerdp* instance) xf_kbd_init(xfi); - xfi->clrconv = xnew(CLRCONV); - xfi->clrconv->alpha = true; - xfi->clrconv->invert = false; - xfi->clrconv->rgb555 = false; - xfi->clrconv->palette = xnew(rdpPalette); + xfi->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA); instance->context->cache = cache_new(instance->settings); @@ -647,21 +643,7 @@ boolean xf_post_connect(freerdp* instance) xfi->srcBpp = instance->settings->color_depth; xf_gdi_register_update_callbacks(instance->update); - xfi->hdc = gdi_GetDC(); - xfi->hdc->bitsPerPixel = xfi->bpp; - xfi->hdc->bytesPerPixel = xfi->bpp / 8; - - xfi->hdc->alpha = xfi->clrconv->alpha; - xfi->hdc->invert = xfi->clrconv->invert; - xfi->hdc->rgb555 = xfi->clrconv->rgb555; - - xfi->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); - xfi->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); - xfi->hdc->hwnd->invalid->null = 1; - - xfi->hdc->hwnd->count = 32; - xfi->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * xfi->hdc->hwnd->count); - xfi->hdc->hwnd->ninvalid = 0; + xfi->hdc = gdi_CreateDC(xfi->clrconv, xfi->bpp); xfi->primary_buffer = (uint8*) xzalloc(xfi->width * xfi->height * xfi->bpp); @@ -922,8 +904,9 @@ void xf_window_free(xfInfo* xfi) rfx_context_free(xfi->rfx_context); xfi->rfx_context = NULL; } - - xfree(xfi->clrconv); + + freerdp_clrconv_free(xfi->clrconv); + gdi_DeleteDC(xfi->hdc); xf_tsmf_uninit(xfi); xf_cliprdr_uninit(xfi); @@ -932,6 +915,10 @@ void xf_window_free(xfInfo* xfi) void xf_free(xfInfo* xfi) { xf_window_free(xfi); + + if (xfi->bmp_codec_none != NULL) + xfree(xfi->bmp_codec_none); + XCloseDisplay(xfi->display); xfree(xfi); } diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index d9e7c60b1..14f305899 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -254,6 +254,9 @@ FREERDP_API uint32 freerdp_color_convert_bgr_rgb(uint32 srcColor, int srcBpp, in FREERDP_API uint32 freerdp_color_convert_var_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); FREERDP_API uint32 freerdp_color_convert_var_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API HCLRCONV freerdp_clrconv_new(uint32 flags); +FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv); + #ifdef __cplusplus } #endif diff --git a/include/freerdp/gdi/dc.h b/include/freerdp/gdi/dc.h index d95f266dd..83fa1152e 100644 --- a/include/freerdp/gdi/dc.h +++ b/include/freerdp/gdi/dc.h @@ -24,6 +24,7 @@ #include FREERDP_API HGDI_DC gdi_GetDC(); +FREERDP_API HGDI_DC gdi_CreateDC(HCLRCONV clrconv, int bpp); FREERDP_API HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc); FREERDP_API HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject); FREERDP_API int gdi_DeleteObject(HGDIOBJECT hgdiobject); diff --git a/libfreerdp-cache/bitmap.c b/libfreerdp-cache/bitmap.c index 6d45e31e8..652a39189 100644 --- a/libfreerdp-cache/bitmap.c +++ b/libfreerdp-cache/bitmap.c @@ -274,7 +274,7 @@ void bitmap_cache_free(rdpBitmapCache* bitmap_cache) } if (bitmap_cache->bitmap != NULL) - bitmap_cache->bitmap->Free(bitmap_cache->context, bitmap_cache->bitmap); + Bitmap_Free(bitmap_cache->context, bitmap_cache->bitmap); xfree(bitmap_cache->cells); xfree(bitmap_cache); diff --git a/libfreerdp-cache/brush.c b/libfreerdp-cache/brush.c index dabf9c038..237a63ec4 100644 --- a/libfreerdp-cache/brush.c +++ b/libfreerdp-cache/brush.c @@ -142,10 +142,32 @@ rdpBrushCache* brush_cache_new(rdpSettings* settings) void brush_cache_free(rdpBrushCache* brush) { + int i; + if (brush != NULL) { - xfree(brush->entries); - xfree(brush->monoEntries); + if (brush->entries != NULL) + { + for (i = 0; i < brush->maxEntries; i++) + { + if (brush->entries[i].entry != NULL) + xfree(brush->entries[i].entry); + } + + xfree(brush->entries); + } + + if (brush->monoEntries != NULL) + { + for (i = 0; i < brush->maxMonoEntries; i++) + { + if (brush->monoEntries[i].entry != NULL) + xfree(brush->monoEntries[i].entry); + } + + xfree(brush->monoEntries); + } + xfree(brush); } } diff --git a/libfreerdp-cache/glyph.c b/libfreerdp-cache/glyph.c index f03415d08..fc3326631 100644 --- a/libfreerdp-cache/glyph.c +++ b/libfreerdp-cache/glyph.c @@ -318,6 +318,9 @@ void update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph) Glyph_New(context, glyph); glyph_cache_put(cache->glyph, cache_glyph->cacheId, glyph_data->cacheIndex, glyph); + + cache_glyph->glyphData[i] = NULL; + xfree(glyph_data); } } @@ -343,6 +346,9 @@ void update_gdi_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_ Glyph_New(context, glyph); glyph_cache_put(cache->glyph, cache_glyph_v2->cacheId, glyph_data->cacheIndex, glyph); + + cache_glyph_v2->glyphData[i] = NULL; + xfree(glyph_data); } } @@ -484,6 +490,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache) rdpGlyph* glyph; glyph = glyph_cache->glyphCache[i].entries[j]; + if (glyph != NULL) { Glyph_Free(glyph_cache->context, glyph); diff --git a/libfreerdp-cache/pointer.c b/libfreerdp-cache/pointer.c index d731e54fb..b34b97f59 100644 --- a/libfreerdp-cache/pointer.c +++ b/libfreerdp-cache/pointer.c @@ -139,17 +139,7 @@ void pointer_cache_free(rdpPointerCache* pointer_cache) pointer = pointer_cache->entries[i]; if (pointer != NULL) - { - pointer->Free(pointer_cache->update->context, pointer); - - if (pointer->xorMaskData != NULL) - xfree(pointer->xorMaskData); - - if (pointer->andMaskData != NULL) - xfree(pointer->andMaskData); - - xfree(pointer); - } + Pointer_Free(pointer_cache->update->context, pointer); } xfree(pointer_cache->entries); diff --git a/libfreerdp-codec/color.c b/libfreerdp-codec/color.c index 1ba42f7e3..97187f811 100644 --- a/libfreerdp-codec/color.c +++ b/libfreerdp-codec/color.c @@ -1036,3 +1036,26 @@ void freerdp_image_swap_color_order(uint8* data, int width, int height) } } } + +HCLRCONV freerdp_clrconv_new(uint32 flags) +{ + HCLRCONV clrconv = xnew(CLRCONV); + + clrconv->alpha = (flags & CLRCONV_ALPHA) ? true : false; + clrconv->invert = (flags & CLRCONV_INVERT) ? true : false; + clrconv->rgb555 = (flags & CLRCONV_RGB555) ? true : false; + clrconv->palette = xnew(rdpPalette); + + return clrconv; +} + +void freerdp_clrconv_free(HCLRCONV clrconv) +{ + if (clrconv != NULL) + { + if (clrconv->palette != NULL) + xfree(clrconv->palette); + + xfree(clrconv); + } +} diff --git a/libfreerdp-core/certificate.c b/libfreerdp-core/certificate.c index 32574ee25..44062e65d 100644 --- a/libfreerdp-core/certificate.c +++ b/libfreerdp-core/certificate.c @@ -402,6 +402,7 @@ boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certifica DEBUG_CERTIFICATE("License Server Certificate"); certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &cert_info); DEBUG_LICENSE("modulus length:%d", cert_info.modulus.length); + freerdp_blob_free(&cert_info.modulus); } else if (numCertBlobs - i == 1) { @@ -486,6 +487,10 @@ void certificate_free(rdpCertificate* certificate) if (certificate != NULL) { certificate_free_x509_certificate_chain(certificate->x509_cert_chain); + + if (certificate->cert_info.modulus.data != NULL) + freerdp_blob_free(&(certificate->cert_info.modulus)); + xfree(certificate); } } diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index 0cf06dfc1..5de0a5d91 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -149,30 +149,30 @@ boolean rdp_client_redirect(rdpRdp* rdp) if (redirection->flags & LB_TARGET_NET_ADDRESS) { xfree(settings->hostname); - settings->hostname = redirection->targetNetAddress.ascii; + settings->hostname = xstrdup(redirection->targetNetAddress.ascii); } else if (redirection->flags & LB_TARGET_FQDN) { xfree(settings->hostname); - settings->hostname = redirection->targetFQDN.ascii; + settings->hostname = xstrdup(redirection->targetFQDN.ascii); } else if (redirection->flags & LB_TARGET_NETBIOS_NAME) { xfree(settings->hostname); - settings->hostname = redirection->targetNetBiosName.ascii; + settings->hostname = xstrdup(redirection->targetNetBiosName.ascii); } } if (redirection->flags & LB_USERNAME) { xfree(settings->username); - settings->username = redirection->username.ascii; + settings->username = xstrdup(redirection->username.ascii); } if (redirection->flags & LB_DOMAIN) { xfree(settings->domain); - settings->domain = redirection->domain.ascii; + settings->domain = xstrdup(redirection->domain.ascii); } if (redirection->flags & LB_PASSWORD) diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index c57b78fff..d8f136d72 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -188,6 +188,7 @@ int credssp_authenticate(rdpCredssp* credssp) credssp->negoToken.length = stream_get_length(s); credssp_encrypt_public_key(credssp, &credssp->pubKeyAuth); credssp_send(credssp, &credssp->negoToken, NULL, &credssp->pubKeyAuth); + freerdp_blob_free(&credssp->pubKeyAuth); /* Encrypted Public Key +1 */ if (credssp_recv(credssp, &credssp->negoToken, NULL, &credssp->pubKeyAuth) < 0) @@ -206,6 +207,7 @@ int credssp_authenticate(rdpCredssp* credssp) credssp_encode_ts_credentials(credssp); credssp_encrypt_ts_credentials(credssp, &credssp->authInfo); credssp_send(credssp, NULL, &credssp->authInfo, NULL); + freerdp_blob_free(&credssp->authInfo); xfree(s); @@ -528,6 +530,7 @@ void credssp_send(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rd } transport_write(credssp->transport, s); + stream_free(s); } /** diff --git a/libfreerdp-core/freerdp.c b/libfreerdp-core/freerdp.c index a78f83aea..fbf2494e4 100644 --- a/libfreerdp-core/freerdp.c +++ b/libfreerdp-core/freerdp.c @@ -187,6 +187,10 @@ void freerdp_context_new(freerdp* instance) void freerdp_context_free(freerdp* instance) { IFCALL(instance->ContextFree, instance, instance->context); + + rdp_free(instance->context->rdp); + graphics_free(instance->context->graphics); + xfree(instance->context); } uint32 freerdp_error_info(freerdp* instance) @@ -213,7 +217,7 @@ void freerdp_free(freerdp* freerdp) { if (freerdp) { - rdp_free(freerdp->context->rdp); + freerdp_context_free(freerdp); xfree(freerdp); } } diff --git a/libfreerdp-core/graphics.c b/libfreerdp-core/graphics.c index 1950479ac..f6b3bab4e 100644 --- a/libfreerdp-core/graphics.c +++ b/libfreerdp-core/graphics.c @@ -108,7 +108,18 @@ void Pointer_New(rdpContext* context, rdpPointer* pointer) void Pointer_Free(rdpContext* context, rdpPointer* pointer) { + if (pointer != NULL) + { + pointer->Free(context, pointer); + if (pointer->xorMaskData) + xfree(pointer->xorMaskData); + + if (pointer->andMaskData) + xfree(pointer->andMaskData); + + xfree(pointer); + } } /* static method */ @@ -207,6 +218,7 @@ void graphics_free(rdpGraphics* graphics) { xfree(graphics->Bitmap_Prototype); xfree(graphics->Pointer_Prototype); + xfree(graphics->Glyph_Prototype); xfree(graphics); } } diff --git a/libfreerdp-core/license.c b/libfreerdp-core/license.c index 830043cc3..60b9f9366 100644 --- a/libfreerdp-core/license.c +++ b/libfreerdp-core/license.c @@ -832,6 +832,7 @@ void license_send_platform_challenge_response_packet(rdpLicense* license) buffer = (uint8*) xmalloc(HWID_LENGTH); rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH); crypto_rc4(rc4, HWID_LENGTH, license->hwid, buffer); + crypto_rc4_free(rc4); #ifdef WITH_DEBUG_LICENSE printf("Licensing Encryption Key:\n"); diff --git a/libfreerdp-core/mppc.c b/libfreerdp-core/mppc.c index 14f7d898d..8e66eb3d8 100644 --- a/libfreerdp-core/mppc.c +++ b/libfreerdp-core/mppc.c @@ -1239,15 +1239,17 @@ struct rdp_mppc* mppc_new(rdpRdp* rdp) { struct rdp_mppc* ptr; - ptr = (struct rdp_mppc *) xmalloc(sizeof (struct rdp_mppc)); + ptr = (struct rdp_mppc*) xmalloc(sizeof(struct rdp_mppc)); + if (!ptr) { printf("mppc_new(): system out of memory\n"); return NULL; } - ptr->history_buf = (uint8 *) xmalloc(RDP6_HISTORY_BUF_SIZE); - ptr->offset_cache = (uint16 *) xzalloc(RDP6_OFFSET_CACHE_SIZE); + ptr->history_buf = (uint8*) xmalloc(RDP6_HISTORY_BUF_SIZE); + ptr->offset_cache = (uint16*) xzalloc(RDP6_OFFSET_CACHE_SIZE); + if (!ptr->history_buf) { printf("mppc_new(): system out of memory\n"); @@ -1257,6 +1259,7 @@ struct rdp_mppc* mppc_new(rdpRdp* rdp) ptr->history_ptr = ptr->history_buf; ptr->history_buf_end = ptr->history_buf + RDP6_HISTORY_BUF_SIZE - 1; + return ptr; } @@ -1279,5 +1282,11 @@ void mppc_free(rdpRdp* rdp) rdp->mppc->history_buf = NULL; rdp->mppc->history_ptr = NULL; } + + if (rdp->mppc->offset_cache) + { + xfree(rdp->mppc->offset_cache); + } + xfree(rdp->mppc); } diff --git a/libfreerdp-core/settings.c b/libfreerdp-core/settings.c index fbac191b7..dbafa5b11 100644 --- a/libfreerdp-core/settings.c +++ b/libfreerdp-core/settings.c @@ -209,6 +209,9 @@ void settings_free(rdpSettings* settings) xfree(settings->glyphCache); xfree(settings->fragCache); key_free(settings->server_key); + xfree(settings->config_path); + xfree(settings->current_path); + xfree(settings->development_path); xfree(settings); } } diff --git a/libfreerdp-gdi/dc.c b/libfreerdp-gdi/dc.c index f433c4c7c..b4f4cedfb 100644 --- a/libfreerdp-gdi/dc.c +++ b/libfreerdp-gdi/dc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -47,6 +48,39 @@ HGDI_DC gdi_GetDC() return hDC; } +/** + * Create a device context.\n + * @msdn{dd144871} + * @return new device context + */ + +HGDI_DC gdi_CreateDC(HCLRCONV clrconv, int bpp) +{ + HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC)); + + hDC->drawMode = GDI_R2_BLACK; + hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0); + hDC->clip->null = 1; + hDC->hwnd = NULL; + + hDC->bitsPerPixel = bpp; + hDC->bytesPerPixel = bpp / 8; + + hDC->alpha = clrconv->alpha; + hDC->invert = clrconv->invert; + hDC->rgb555 = clrconv->rgb555; + + hDC->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); + hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + hDC->hwnd->invalid->null = 1; + + hDC->hwnd->count = 32; + hDC->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * hDC->hwnd->count); + hDC->hwnd->ninvalid = 0; + + return hDC; +} + /** * Create a new device context compatible with the given device context.\n * @msdn{dd183489} @@ -182,8 +216,12 @@ int gdi_DeleteDC(HGDI_DC hdc) { if (hdc->hwnd) { - free(hdc->hwnd->cinvalid); - free(hdc->hwnd->invalid); + if (hdc->hwnd->cinvalid != NULL) + free(hdc->hwnd->cinvalid); + + if (hdc->hwnd->invalid != NULL) + free(hdc->hwnd->invalid); + free(hdc->hwnd); }