From b06e50479e3ca49895b92e85717d9be463453b1e Mon Sep 17 00:00:00 2001 From: Clive Stevens Date: Wed, 6 May 2015 15:23:37 +0100 Subject: [PATCH] Fix two cases of potentially leaked streams --- libfreerdp/core/fastpath.c | 32 ++++++++++++++++++++------------ libfreerdp/core/rdp.c | 33 +++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 14ea6b8..004ca5c 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -403,14 +403,14 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (fastpath->fragmentation != -1) { WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_SINGLE"); - return -1; + goto out_fail; } totalSize = size; status = fastpath_recv_update(fastpath, updateCode, totalSize, cs); if (status < 0) - return -1; + goto out_fail; } else { @@ -419,7 +419,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (fastpath->fragmentation != -1) { WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_FIRST"); - return -1; + goto out_fail; } fastpath->fragmentation = FASTPATH_FRAGMENT_FIRST; @@ -430,11 +430,11 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", totalSize, transport->settings->MultifragMaxRequestSize); - return -1; + goto out_fail; } if (!(fastpath->updateData = StreamPool_Take(transport->ReceivePool, size))) - return -1; + goto out_fail; Stream_SetPosition(fastpath->updateData, 0); @@ -446,7 +446,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) { WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_NEXT"); - return -1; + goto out_fail; } fastpath->fragmentation = FASTPATH_FRAGMENT_NEXT; @@ -457,13 +457,13 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", totalSize, transport->settings->MultifragMaxRequestSize); - return -1; + goto out_fail; } if (!Stream_EnsureCapacity(fastpath->updateData, totalSize)) { WLog_ERR(TAG, "Couldn't re-allocate memory for stream"); - return -1; + goto out_fail; } Stream_Copy(fastpath->updateData, cs, size); @@ -474,7 +474,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) { WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_LAST"); - return -1; + goto out_fail; } fastpath->fragmentation = -1; @@ -485,13 +485,13 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", totalSize, transport->settings->MultifragMaxRequestSize); - return -1; + goto out_fail; } if (!Stream_EnsureCapacity(fastpath->updateData, totalSize)) { WLog_ERR(TAG, "Couldn't re-allocate memory for stream"); - return -1; + goto out_fail; } Stream_Copy(fastpath->updateData, cs, size); @@ -504,7 +504,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) Stream_Release(fastpath->updateData); if (status < 0) - return -1; + goto out_fail; } } @@ -514,6 +514,14 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) Stream_Release(cs); return status; + +out_fail: + + if (cs != s) { + Stream_Release(cs); + } + + return -1; } int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s) diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 6fcff23..6710884 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -815,72 +815,72 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) { case DATA_PDU_TYPE_UPDATE: if (!update_recv(rdp->update, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_CONTROL: if (!rdp_recv_server_control_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_POINTER: if (!update_recv_pointer(rdp->update, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_synchronize_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_PLAY_SOUND: if (!update_recv_play_sound(rdp->update, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: if (!rdp_recv_server_shutdown_denied_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: if (!rdp_recv_save_session_info(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_FONT_MAP: if (!rdp_recv_font_map_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: if (!rdp_recv_server_set_keyboard_indicators_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: if (!rdp_recv_server_set_keyboard_ime_status_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_SET_ERROR_INFO: if (!rdp_recv_set_error_info_data_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_ARC_STATUS: if (!rdp_recv_server_auto_reconnect_status_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_STATUS_INFO: if (!rdp_recv_server_status_info_pdu(rdp, cs)) - return -1; + goto out_fail; break; case DATA_PDU_TYPE_MONITOR_LAYOUT: if (!rdp_recv_monitor_layout_pdu(rdp, cs)) - return -1; + goto out_fail; break; default: @@ -891,6 +891,11 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) Stream_Release(cs); return 0; + +out_fail: + if (cs != s) + Stream_Release(cs); + return -1; } int rdp_recv_message_channel_pdu(rdpRdp* rdp, wStream* s) -- 2.7.4