libfreerdp-core: fix potential crash on session redirection failure

This commit is contained in:
Marc-André Moreau 2014-04-28 16:44:52 -04:00
parent e192e0c141
commit c2a59c23a7
6 changed files with 31 additions and 26 deletions

View File

@ -3486,14 +3486,16 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s)
return FALSE; return FALSE;
} }
rdp->settings->PduSource = pduSource;
if (pduType != PDU_TYPE_DEMAND_ACTIVE) if (pduType != PDU_TYPE_DEMAND_ACTIVE)
{ {
if (pduType != PDU_TYPE_SERVER_REDIRECTION)
fprintf(stderr, "expected PDU_TYPE_DEMAND_ACTIVE %04x, got %04x\n", PDU_TYPE_DEMAND_ACTIVE, pduType); fprintf(stderr, "expected PDU_TYPE_DEMAND_ACTIVE %04x, got %04x\n", PDU_TYPE_DEMAND_ACTIVE, pduType);
return FALSE; return FALSE;
} }
rdp->settings->PduSource = pduSource;
if (Stream_GetRemainingLength(s) < 8) if (Stream_GetRemainingLength(s) < 8)
return FALSE; return FALSE;

View File

@ -179,6 +179,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
} }
rdp->settingsCopy = freerdp_settings_clone(settings); rdp->settingsCopy = freerdp_settings_clone(settings);
if (!rdp->settingsCopy) if (!rdp->settingsCopy)
return FALSE; return FALSE;

View File

@ -1186,7 +1186,14 @@ void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking)
int rdp_check_fds(rdpRdp* rdp) int rdp_check_fds(rdpRdp* rdp)
{ {
int status; int status;
status = transport_check_fds(rdp->transport); status = transport_check_fds(rdp->transport);
if (status == 1)
{
status = rdp_client_redirect(rdp); /* session redirection */
}
return status; return status;
} }

View File

@ -314,7 +314,7 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
if (redirection->flags & LB_NOREDIRECT) if (redirection->flags & LB_NOREDIRECT)
return 0; return 0;
return rdp_client_redirect(rdp); return 1;
} }
int rdp_recv_redirection_packet(rdpRdp* rdp, wStream* s) int rdp_recv_redirection_packet(rdpRdp* rdp, wStream* s)
@ -346,12 +346,10 @@ rdpRedirection* redirection_new()
{ {
rdpRedirection* redirection; rdpRedirection* redirection;
redirection = (rdpRedirection*) malloc(sizeof(rdpRedirection)); redirection = (rdpRedirection*) calloc(1, sizeof(rdpRedirection));
if (redirection) if (redirection)
{ {
ZeroMemory(redirection, sizeof(rdpRedirection));
WLog_Init(); WLog_Init();
redirection->log = WLog_Get("com.freerdp.core.redirection"); redirection->log = WLog_Get("com.freerdp.core.redirection");

View File

@ -1079,20 +1079,15 @@ int transport_check_fds(rdpTransport* transport)
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
if (recv_status == 1)
{
/**
* Last call to ReceiveCallback resulted in a session redirection,
* which means the current rdpTransport* transport pointer has been freed.
* Return 0 for success, the rest of this function is meant for non-redirected cases.
*/
return 0;
}
Stream_Release(received); Stream_Release(received);
if (recv_status < 0) if (recv_status < 0)
return -1; return -1;
if (recv_status == 1)
{
return 1; /* session redirection */
}
} }
return 0; return 0;

View File

@ -324,26 +324,28 @@ wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize)
{ {
wStreamPool* pool = NULL; wStreamPool* pool = NULL;
pool = (wStreamPool*) malloc(sizeof(wStreamPool)); pool = (wStreamPool*) calloc(1, sizeof(wStreamPool));
if (pool) if (pool)
{ {
ZeroMemory(pool, sizeof(wStreamPool));
pool->synchronized = synchronized; pool->synchronized = synchronized;
pool->defaultSize = defaultSize; pool->defaultSize = defaultSize;
InitializeCriticalSectionAndSpinCount(&pool->lock, 4000);
pool->aSize = 0; pool->aSize = 0;
pool->aCapacity = 32; pool->aCapacity = 32;
pool->aArray = (wStream**) malloc(sizeof(wStream*) * pool->aCapacity); pool->aArray = (wStream**) calloc(pool->aCapacity, sizeof(wStream*));
ZeroMemory(pool->aArray, sizeof(wStream*) * pool->aCapacity);
if (!pool->aArray)
return NULL;
pool->uSize = 0; pool->uSize = 0;
pool->uCapacity = 32; pool->uCapacity = 32;
pool->uArray = (wStream**) malloc(sizeof(wStream*) * pool->uCapacity); pool->uArray = (wStream**) calloc(pool->uCapacity, sizeof(wStream*));
ZeroMemory(pool->uArray, sizeof(wStream*) * pool->uCapacity);
if (!pool->uArray)
return NULL;
InitializeCriticalSectionAndSpinCount(&pool->lock, 4000);
} }
return pool; return pool;