From d284d024b681b425a3561f015827b4fa7d0ee5ab Mon Sep 17 00:00:00 2001 From: Joan Torres Date: Mon, 2 Dec 2024 17:28:36 +0100 Subject: [PATCH 1/2] [core,rdstls] fix rdstls parsing When parsing the rdstls PDU, don't set the stream position at the end. To know the pduLength is enough getting the last field length and the stream position. This fixes transport_read_layer_bytes failing because it was getting on toRead = 0. --- libfreerdp/core/rdstls.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libfreerdp/core/rdstls.c b/libfreerdp/core/rdstls.c index 1d79158fe..247f63914 100644 --- a/libfreerdp/core/rdstls.c +++ b/libfreerdp/core/rdstls.c @@ -936,6 +936,8 @@ int rdstls_authenticate(rdpRdstls* rdstls) static SSIZE_T rdstls_parse_pdu_data_type(wLog* log, UINT16 dataType, wStream* s) { + size_t pduLength = 0; + switch (dataType) { case RDSTLS_DATA_PASSWORD_CREDS: @@ -972,9 +974,7 @@ static SSIZE_T rdstls_parse_pdu_data_type(wLog* log, UINT16 dataType, wStream* s return 0; Stream_Read_UINT16(s, passwordLength); - if (Stream_GetRemainingLength(s) < passwordLength) - return 0; - Stream_Seek(s, passwordLength); + pduLength = Stream_GetPosition(s) + passwordLength; } break; case RDSTLS_DATA_AUTORECONNECT_COOKIE: @@ -987,8 +987,8 @@ static SSIZE_T rdstls_parse_pdu_data_type(wLog* log, UINT16 dataType, wStream* s if (Stream_GetRemainingLength(s) < 2) return 0; Stream_Read_UINT16(s, cookieLength); - if (!Stream_SafeSeek(s, cookieLength)) - return 0; + + pduLength = Stream_GetPosition(s) + cookieLength; } break; default: @@ -996,10 +996,9 @@ static SSIZE_T rdstls_parse_pdu_data_type(wLog* log, UINT16 dataType, wStream* s return -1; } - const size_t len = Stream_GetPosition(s); - if (len > SSIZE_MAX) + if (pduLength > SSIZE_MAX) return 0; - return (SSIZE_T)len; + return (SSIZE_T)pduLength; } SSIZE_T rdstls_parse_pdu(wLog* log, wStream* stream) From 6d0381e36e9688f233091fcb7b428dbb1b7747f7 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Tue, 3 Dec 2024 08:46:37 +0100 Subject: [PATCH 2/2] [core,transport] fix reading of data in transport_default_read_pdu only try to read the remaining PDU bytes if we did not already complete that. Calling transport_read_layer_bytes with a length of 0 returns 0 whereas every other value returns 1 for success. --- libfreerdp/core/transport.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 144a6c55b..eae6046e5 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -1114,14 +1114,15 @@ static int transport_default_read_pdu(rdpTransport* transport, wStream* s) position = Stream_GetPosition(s); if (position > pduLength) return -1; - - status = transport_read_layer_bytes(transport, s, pduLength - Stream_GetPosition(s)); - - if (status != 1) + else if (position < pduLength) { - if ((status < INT32_MIN) || (status > INT32_MAX)) - return -1; - return (int)status; + status = transport_read_layer_bytes(transport, s, pduLength - position); + if (status != 1) + { + if ((status < INT32_MIN) || (status > INT32_MAX)) + return -1; + return (int)status; + } } if (Stream_GetPosition(s) >= pduLength)