libfreerdp-core: fix memory leaks reported by valgrind

This commit is contained in:
Marc-André Moreau 2013-10-31 23:35:24 -04:00
parent 3bc47a2bf8
commit 1fc2d780f7
12 changed files with 113 additions and 40 deletions

View File

@ -728,8 +728,12 @@ static void xf_post_disconnect(freerdp *instance)
assert(NULL != xfc); assert(NULL != xfc);
assert(NULL != instance->settings); assert(NULL != instance->settings);
if (xfc->mutex)
{
WaitForSingleObject(xfc->mutex, INFINITE); WaitForSingleObject(xfc->mutex, INFINITE);
CloseHandle(xfc->mutex); CloseHandle(xfc->mutex);
xfc->mutex = NULL;
}
xf_monitors_free(xfc, instance->settings); xf_monitors_free(xfc, instance->settings);
} }
@ -938,6 +942,10 @@ BOOL xf_post_connect(freerdp* instance)
xf_create_window(xfc); xf_create_window(xfc);
ZeroMemory(&gcv, sizeof(gcv)); ZeroMemory(&gcv, sizeof(gcv));
if (xfc->modifier_map)
XFreeModifiermap(xfc->modifier_map);
xfc->modifier_map = XGetModifierMapping(xfc->display); xfc->modifier_map = XGetModifierMapping(xfc->display);
xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv); xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv);
@ -1389,6 +1397,15 @@ void* xf_thread(void* param)
if (!status) if (!status)
{ {
if (xfc->mutex)
{
WaitForSingleObject(xfc->mutex, INFINITE);
CloseHandle(xfc->mutex);
xfc->mutex = NULL;
}
xf_monitors_free(xfc, instance->settings);
exit_code = XF_EXIT_CONN_FAILED; exit_code = XF_EXIT_CONN_FAILED;
ExitThread(exit_code); ExitThread(exit_code);
} }
@ -1830,7 +1847,6 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler); PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler);
PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler); PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler);
return 0; return 0;
} }

View File

@ -475,7 +475,9 @@ static BOOL xf_event_MappingNotify(xfContext* xfc, XEvent* event, BOOL app)
{ {
if (event->xmapping.request == MappingModifier) if (event->xmapping.request == MappingModifier)
{ {
if (xfc->modifier_map)
XFreeModifiermap(xfc->modifier_map); XFreeModifiermap(xfc->modifier_map);
xfc->modifier_map = XGetModifierMapping(xfc->display); xfc->modifier_map = XGetModifierMapping(xfc->display);
} }

View File

@ -38,9 +38,14 @@
void xf_kbd_init(xfContext* xfc) void xf_kbd_init(xfContext* xfc)
{ {
xf_kbd_clear(xfc); xf_kbd_clear(xfc);
xfc->keyboard_layout_id = xfc->instance->settings->KeyboardLayout; xfc->keyboard_layout_id = xfc->instance->settings->KeyboardLayout;
xfc->keyboard_layout_id = freerdp_keyboard_init(xfc->keyboard_layout_id); xfc->keyboard_layout_id = freerdp_keyboard_init(xfc->keyboard_layout_id);
xfc->instance->settings->KeyboardLayout = xfc->keyboard_layout_id; xfc->instance->settings->KeyboardLayout = xfc->keyboard_layout_id;
if (xfc->modifier_map)
XFreeModifiermap(xfc->modifier_map);
xfc->modifier_map = XGetModifierMapping(xfc->display); xfc->modifier_map = XGetModifierMapping(xfc->display);
} }

View File

@ -262,9 +262,15 @@ void xf_monitors_free(xfContext *xfc, rdpSettings *settings)
{ {
#ifdef WITH_XINERAMA #ifdef WITH_XINERAMA
if (xfc->vscreen.monitors) if (xfc->vscreen.monitors)
{
free(xfc->vscreen.monitors); free(xfc->vscreen.monitors);
xfc->vscreen.monitors = NULL;
}
#endif #endif
if (settings->MonitorIds) if (settings->MonitorIds)
{
free(settings->MonitorIds); free(settings->MonitorIds);
settings->MonitorIds = NULL;
}
} }

View File

@ -58,7 +58,6 @@ FREERDP_API BOOL tls_disconnect(rdpTls* tls);
FREERDP_API int tls_read(rdpTls* tls, BYTE* data, int length); FREERDP_API int tls_read(rdpTls* tls, BYTE* data, int length);
FREERDP_API int tls_write(rdpTls* tls, BYTE* data, int length); FREERDP_API int tls_write(rdpTls* tls, BYTE* data, int length);
FREERDP_API int tls_read_all(rdpTls* tls, BYTE* data, int length);
FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length); FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length);
FREERDP_API int tls_wait_read(rdpTls* tls); FREERDP_API int tls_wait_read(rdpTls* tls);

View File

@ -364,6 +364,8 @@ BOOL rdp_client_redirect(rdpRdp* rdp)
return rdp_client_connect(rdp); return rdp_client_connect(rdp);
} }
static BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
static BOOL rdp_client_establish_keys(rdpRdp* rdp) static BOOL rdp_client_establish_keys(rdpRdp* rdp)
{ {
BYTE* mod; BYTE* mod;
@ -380,10 +382,17 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
} }
/* encrypt client random */ /* encrypt client random */
if (rdp->settings->ClientRandom) free(rdp->settings->ClientRandom);
if (rdp->settings->ClientRandom)
free(rdp->settings->ClientRandom);
rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH); rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH);
if (rdp->settings->ClientRandom == NULL) return FALSE;
if (!rdp->settings->ClientRandom)
return FALSE;
ZeroMemory(crypt_client_random, sizeof(crypt_client_random)); ZeroMemory(crypt_client_random, sizeof(crypt_client_random));
crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH); crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH);
key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength; key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength;
mod = rdp->settings->RdpServerCertificate->cert_info.Modulus; mod = rdp->settings->RdpServerCertificate->cert_info.Modulus;
@ -422,7 +431,6 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
{ {
BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
@ -503,7 +511,6 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
{ {
BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);

View File

@ -139,18 +139,28 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings)
if (Stream_GetRemainingLength(s) < cbClientAddress) if (Stream_GetRemainingLength(s) < cbClientAddress)
return FALSE; return FALSE;
if (settings->ClientAddress)
{
free(settings->ClientAddress);
settings->ClientAddress = NULL;
}
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL); ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL);
Stream_Seek(s, cbClientAddress); Stream_Seek(s, cbClientAddress);
if (Stream_GetRemainingLength(s) < 2) if (Stream_GetRemainingLength(s) < 2)
return FALSE; return FALSE;
Stream_Read_UINT16(s, cbClientDir); /* cbClientDir */ Stream_Read_UINT16(s, cbClientDir); /* cbClientDir */
if (Stream_GetRemainingLength(s) < cbClientDir) if (Stream_GetRemainingLength(s) < cbClientDir)
return FALSE; return FALSE;
if (settings->ClientDir) if (settings->ClientDir)
{
free(settings->ClientDir); free(settings->ClientDir);
settings->ClientDir = NULL;
}
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientDir / 2, &settings->ClientDir, 0, NULL, NULL); ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientDir / 2, &settings->ClientDir, 0, NULL, NULL);
Stream_Seek(s, cbClientDir); Stream_Seek(s, cbClientDir);
@ -238,7 +248,9 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings)
clientCookie->logonId = serverCookie->logonId; clientCookie->logonId = serverCookie->logonId;
hmac = crypto_hmac_new(); hmac = crypto_hmac_new();
crypto_hmac_md5_init(hmac, serverCookie->arcRandomBits, 16); crypto_hmac_md5_init(hmac, serverCookie->arcRandomBits, 16);
if (settings->SelectedProtocol == PROTOCOL_RDP) if (settings->SelectedProtocol == PROTOCOL_RDP)
{ {
crypto_hmac_update(hmac, (BYTE*) (settings->ClientRandom), 32); crypto_hmac_update(hmac, (BYTE*) (settings->ClientRandom), 32);

View File

@ -1669,7 +1669,11 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_
return FALSE; return FALSE;
if (glyph->aj) if (glyph->aj)
{
free(glyph->aj); free(glyph->aj);
glyph->aj = NULL;
}
glyph->aj = (BYTE*) malloc(glyph->cb); glyph->aj = (BYTE*) malloc(glyph->cb);
Stream_Read(s, glyph->aj, glyph->cb); Stream_Read(s, glyph->aj, glyph->cb);
} }

View File

@ -96,6 +96,7 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
if (Stream_GetRemainingLength(s) < 12) if (Stream_GetRemainingLength(s) < 12)
return FALSE; return FALSE;
Stream_Read_UINT16(s, flags); /* flags (2 bytes) */ Stream_Read_UINT16(s, flags); /* flags (2 bytes) */
Stream_Read_UINT16(s, length); /* length (2 bytes) */ Stream_Read_UINT16(s, length); /* length (2 bytes) */
Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */ Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */

View File

@ -79,6 +79,13 @@ void tcp_get_ip_address(rdpTcp * tcp)
tcp->ip_address[sizeof(tcp->ip_address) - 1] = 0; tcp->ip_address[sizeof(tcp->ip_address) - 1] = 0;
tcp->settings->IPv6Enabled = 0; tcp->settings->IPv6Enabled = 0;
if (tcp->settings->ClientAddress)
{
free(tcp->settings->ClientAddress);
tcp->settings->ClientAddress = NULL;
}
tcp->settings->ClientAddress = _strdup(tcp->ip_address); tcp->settings->ClientAddress = _strdup(tcp->ip_address);
} }

View File

@ -218,7 +218,6 @@ BOOL transport_connect_tls(rdpTransport* transport)
connectErrorCode = TLSCONNECTERROR; connectErrorCode = TLSCONNECTERROR;
tls_free(transport->TsgTls); tls_free(transport->TsgTls);
transport->TsgTls = NULL; transport->TsgTls = NULL;
return FALSE; return FALSE;
@ -537,6 +536,12 @@ int transport_read(rdpTransport* transport, wStream* s)
pduLength = 0; pduLength = 0;
transport_status = 0; transport_status = 0;
if (!transport)
return -1;
if (!s)
return -1;
/* first check if we have header */ /* first check if we have header */
streamPosition = Stream_GetPosition(s); streamPosition = Stream_GetPosition(s);
@ -790,6 +795,9 @@ int transport_check_fds(rdpTransport** ptransport)
wStream* received; wStream* received;
rdpTransport* transport = *ptransport; rdpTransport* transport = *ptransport;
if (!transport)
return -1;
#ifdef _WIN32 #ifdef _WIN32
WSAResetEvent(transport->TcpIn->wsa_event); WSAResetEvent(transport->TcpIn->wsa_event);
#endif #endif
@ -881,10 +889,11 @@ int transport_check_fds(rdpTransport** ptransport)
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
if (transport == *ptransport) if (transport == *ptransport)
{
/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
/* so only release if still valid */ /* so only release if still valid */
Stream_Release(received); Stream_Release(received);
}
if (recv_status < 0) if (recv_status < 0)
status = -1; status = -1;
@ -1029,12 +1038,20 @@ void transport_free(rdpTransport* transport)
if (transport->TlsOut != transport->TlsIn) if (transport->TlsOut != transport->TlsIn)
tls_free(transport->TlsOut); tls_free(transport->TlsOut);
transport->TlsIn = NULL;
transport->TlsOut = NULL;
if (transport->TcpIn)
tcp_free(transport->TcpIn); tcp_free(transport->TcpIn);
if (transport->TcpOut != transport->TcpIn) if (transport->TcpOut != transport->TcpIn)
tcp_free(transport->TcpOut); tcp_free(transport->TcpOut);
transport->TcpIn = NULL;
transport->TcpOut = NULL;
tsg_free(transport->tsg); tsg_free(transport->tsg);
transport->tsg = NULL;
CloseHandle(transport->ReadMutex); CloseHandle(transport->ReadMutex);
CloseHandle(transport->WriteMutex); CloseHandle(transport->WriteMutex);

View File

@ -371,9 +371,15 @@ int tls_read(rdpTls* tls, BYTE* data, int length)
int error; int error;
int status; int status;
status = tls ? SSL_read(tls->ssl, data, length) : -1; if (!tls)
return -1;
if (tls && status <= 0) if (!tls->ssl)
return -1;
status = SSL_read(tls->ssl, data, length);
if (status <= 0)
{ {
error = SSL_get_error(tls->ssl, status); error = SSL_get_error(tls->ssl, status);
@ -412,26 +418,17 @@ int tls_read(rdpTls* tls, BYTE* data, int length)
return status; return status;
} }
int tls_read_all(rdpTls* tls, BYTE* data, int length)
{
int status;
do
{
status = tls_read(tls, data, length);
if (status == 0)
tls_wait_read(tls);
}
while (status == 0);
return status;
}
int tls_write(rdpTls* tls, BYTE* data, int length) int tls_write(rdpTls* tls, BYTE* data, int length)
{ {
int error; int error;
int status; int status;
if (!tls)
return -1;
if (!tls->ssl)
return -1;
status = SSL_write(tls->ssl, data, length); status = SSL_write(tls->ssl, data, length);
if (status <= 0) if (status <= 0)
@ -777,7 +774,7 @@ rdpTls* tls_new(rdpSettings* settings)
tls = (rdpTls*) malloc(sizeof(rdpTls)); tls = (rdpTls*) malloc(sizeof(rdpTls));
if (tls != NULL) if (tls)
{ {
ZeroMemory(tls, sizeof(rdpTls)); ZeroMemory(tls, sizeof(rdpTls));
@ -793,7 +790,7 @@ rdpTls* tls_new(rdpSettings* settings)
void tls_free(rdpTls* tls) void tls_free(rdpTls* tls)
{ {
if (tls != NULL) if (tls)
{ {
if (tls->ssl) if (tls->ssl)
{ {