From 2c00240a176413bb2b48c791cf2bac272e106b5d Mon Sep 17 00:00:00 2001 From: "zihao.jiang" Date: Sat, 27 Aug 2016 21:51:29 +0800 Subject: [PATCH] server/shadow: Fix regression with rdp8.0 Shadow server crash with rdp8.0 with gfx enabled. Root Cause: rdp8.0 is not support in shadow gfx and rdpgfx_caps_advertise returns an error. However setChannelError crashs because context->errorDescription is NULL 1. Fix shadow gfx to handle rdp8.0 2. Initialize context->errorDescription for server side new-context --- libfreerdp/core/peer.c | 28 ++++++++++++++++++++++------ server/shadow/shadow_rdpgfx.c | 19 ++++++++++++++++++- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 6462d46..482f855 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -716,6 +716,12 @@ BOOL freerdp_peer_context_new(freerdp_peer* client) update_register_server_callbacks(client->update); autodetect_register_server_callbacks(client->autodetect); + if (!(context->errorDescription = calloc(1, 500))) + { + WLog_ERR(TAG, "calloc failed!"); + goto fail_error_description; + } + if (!transport_attach(rdp->transport, client->sockfd)) goto fail_transport_attach; @@ -734,6 +740,8 @@ BOOL freerdp_peer_context_new(freerdp_peer* client) WLog_ERR(TAG, "ContextNew callback failed"); fail_transport_attach: + free(context->errorDescription); +fail_error_description: rdp_free(client->context->rdp); fail_rdp: metrics_free(context->metrics); @@ -750,7 +758,20 @@ void freerdp_peer_context_free(freerdp_peer* client) { IFCALL(client->ContextFree, client, client->context); - metrics_free(client->context->metrics); + if (client->context) + { + free(client->context->errorDescription); + client->context->errorDescription = NULL; + + rdp_free(client->context->rdp); + client->context->rdp = NULL; + + metrics_free(client->context->metrics); + client->context->metrics = NULL; + + free(client->context); + client->context = NULL; + } } freerdp_peer* freerdp_peer_new(int sockfd) @@ -798,10 +819,5 @@ void freerdp_peer_free(freerdp_peer* client) if (!client) return; - if (client->context) - { - rdp_free(client->context->rdp); - free(client->context); - } free(client); } diff --git a/server/shadow/shadow_rdpgfx.c b/server/shadow/shadow_rdpgfx.c index a8ad115..cdf3f39 100644 --- a/server/shadow/shadow_rdpgfx.c +++ b/server/shadow/shadow_rdpgfx.c @@ -53,7 +53,10 @@ static UINT rdpgfx_caps_advertise(RdpgfxServerContext* context, RDPGFX_CAPS_ADVE return context->CapsConfirm(context, &pdu); } - else if (pdu.capsSet->version == RDPGFX_CAPVERSION_81) + } + for (index = 0; index < capsAdvertise->capsSetCount; index++) + { + if (pdu.capsSet->version == RDPGFX_CAPVERSION_81) { if (settings) { @@ -66,6 +69,20 @@ static UINT rdpgfx_caps_advertise(RdpgfxServerContext* context, RDPGFX_CAPS_ADVE return context->CapsConfirm(context, &pdu); } } + for (index = 0; index < capsAdvertise->capsSetCount; index++) + { + if (pdu.capsSet->version == RDPGFX_CAPVERSION_8) + { + if (settings) + { + flags = pdu.capsSet->flags; + settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_THINCLIENT); + settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE); + } + + return context->CapsConfirm(context, &pdu); + } + } return CHANNEL_RC_UNSUPPORTED_VERSION; } -- 2.7.4