Package: release.debian.org Severity: normal Tags: buster User: release.debian....@packages.debian.org Usertags: pu
Dear release team, I just uploaded this update of freerdp2 to Debian buster. Thanks to Bernhard Miklautz, we have several security patches available: + [ Bernhard Miklautz ] + * debian/patches - security releated backports from upstream + * Add 0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch + * Add 0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch + * Add 0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch + * Add 0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch + * Add 0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch + * Add 0008-Fixed-6013-Check-new-length-is-0.patch + * Add 0009-Fix-6010-Check-length-in-read_icon_info.patch + * Add 0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch + * Add 0011-Fixed-Stream_-macros-bracing-arguments.patch + * Add 0012-Use-safe-seek-for-capability-parsing.patch + * Add 0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch + (CVE-2020-11525). + * Add 0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch + (CVE-2020-11526). + * Add 0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch + (CVE-2020-11523). + * Add 0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch + (CVE-2020-11524). + * Add 0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch + (CVE-2020-11522). + * Add 0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch + (CVE-2020-11521). + * Add 0019-Fixed-possible-NULL-access.patch + * Add 0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch -> This patchwork will be the first round of CVE closures (all no-dsa, as discussed with Salvatore from the security team). Whenever Bernhard finds time, he will provide more patches and a +deb10u3 is probably already in sight. + [ Mike Gabriel ] + * debian/patches: + + Add 0002_fix-channels-smartcard-fix-statusw-call.patch. Fix smartcard + login failures. (Closes: #919281). -> a functionality fix for people using smartcard readers with FreeRDP. Thanks+Greets, Mike -- System Information: Debian Release: 10.4 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'proposed-updates'), (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.19.0-8-amd64 (SMP w/4 CPU cores) Kernel taint flags: TAINT_WARN, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled
diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/changelog freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/changelog --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/changelog 2019-12-16 11:36:02.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/changelog 2020-06-01 13:08:46.000000000 +0200 @@ -1,3 +1,39 @@ +freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u2) buster; urgency=medium + + [ Bernhard Miklautz ] + * debian/patches - security releated backports from upstream + * Add 0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch + * Add 0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch + * Add 0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch + * Add 0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch + * Add 0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch + * Add 0008-Fixed-6013-Check-new-length-is-0.patch + * Add 0009-Fix-6010-Check-length-in-read_icon_info.patch + * Add 0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch + * Add 0011-Fixed-Stream_-macros-bracing-arguments.patch + * Add 0012-Use-safe-seek-for-capability-parsing.patch + * Add 0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch + (CVE-2020-11525). + * Add 0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch + (CVE-2020-11526). + * Add 0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch + (CVE-2020-11523). + * Add 0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch + (CVE-2020-11524). + * Add 0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch + (CVE-2020-11522). + * Add 0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch + (CVE-2020-11521). + * Add 0019-Fixed-possible-NULL-access.patch + * Add 0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch + + [ Mike Gabriel ] + * debian/patches: + + Add 0002_fix-channels-smartcard-fix-statusw-call.patch. Fix smartcard + login failures. (Closes: #919281). + + -- Mike Gabriel <sunwea...@debian.org> Mon, 01 Jun 2020 13:08:46 +0200 + freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u1) buster; urgency=medium * debian/patches: diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0002_fix-channels-smartcard-fix-statusw-call.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0002_fix-channels-smartcard-fix-statusw-call.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0002_fix-channels-smartcard-fix-statusw-call.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0002_fix-channels-smartcard-fix-statusw-call.patch 2020-06-01 13:05:29.000000000 +0200 @@ -0,0 +1,46 @@ +From a311075202865d22b87ec2ea8d1e32fa11868012 Mon Sep 17 00:00:00 2001 +From: Bernhard Miklautz <bernhard.mikla...@thincast.com> +Date: Wed, 10 Jul 2019 18:36:34 +0200 +Subject: [PATCH] fix [channels/smartcard]: fix StatusW_Call + +According to 2.2.2.18 Status_Call cbAtrLen is unused an must be ignored +upon receipt. +--- + channels/smartcard/client/smartcard_operations.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/channels/smartcard/client/smartcard_operations.c ++++ b/channels/smartcard/client/smartcard_operations.c +@@ -1204,15 +1204,19 @@ + Status_Call* call = operation->call; + DWORD cbAtrLen; + +- if (call->cbAtrLen > 32) +- call->cbAtrLen = 32; ++ /** ++ * [MS-RDPESC] ++ * According to 2.2.2.18 Status_Call cbAtrLen is unused an must be ignored upon receipt. ++ */ ++ cbAtrLen = call->cbAtrLen = 32; ++ ++ call->cchReaderLen; + + if (call->fmszReaderNamesIsNULL) + cchReaderLen = 0; + else + cchReaderLen = SCARD_AUTOALLOCATE; + +- cbAtrLen = call->cbAtrLen; + ZeroMemory(ret.pbAtr, 32); + status = ret.ReturnCode = SCardStatusW(operation->hCard, + call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames, +@@ -1231,8 +1235,7 @@ + ret.cBytes = cchReaderLen; + #endif + +- if (call->cbAtrLen) +- ret.cbAtrLen = cbAtrLen; ++ ret.cbAtrLen = cbAtrLen; + } + + smartcard_trace_status_return(smartcard, &ret, TRUE); diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,81 @@ +--- a/libfreerdp/core/rdp.c ++++ b/libfreerdp/core/rdp.c +@@ -110,29 +110,33 @@ void rdp_write_security_header(wStream* s, UINT16 flags) + + BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id) + { ++ UINT16 len; + if (Stream_GetRemainingLength(s) < 2) + return FALSE; + + /* Share Control Header */ +- Stream_Read_UINT16(s, *length); /* totalLength */ ++ Stream_Read_UINT16(s, len); /* totalLength */ ++ ++ *length = len; + + /* If length is 0x8000 then we actually got a flow control PDU that we should ignore + http://msdn.microsoft.com/en-us/library/cc240576.aspx */ +- if (*length == 0x8000) ++ if (len == 0x8000) + { +- rdp_read_flow_control_pdu(s, type); ++ if (!rdp_read_flow_control_pdu(s, type)) ++ return FALSE; + *channel_id = 0; + *length = 8; /* Flow control PDU is 8 bytes */ + return TRUE; + } + +- if (((size_t) *length - 2) > Stream_GetRemainingLength(s)) ++ if ((len < 4) || ((len - 2) > Stream_GetRemainingLength(s))) + return FALSE; + + Stream_Read_UINT16(s, *type); /* pduType */ + *type &= 0x0F; /* type is in the 4 least significant bits */ + +- if (*length > 4) ++ if (len > 4) + Stream_Read_UINT16(s, *channel_id); /* pduSource */ + else + *channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */ +@@ -1088,7 +1092,7 @@ int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s) + } + } + +-void rdp_read_flow_control_pdu(wStream* s, UINT16* type) ++BOOL rdp_read_flow_control_pdu(wStream* s, UINT16* type) + { + /* + * Read flow control PDU - documented in FlowPDU section in T.128 +@@ -1098,12 +1102,17 @@ void rdp_read_flow_control_pdu(wStream* s, UINT16* type) + * Switched the order of these two fields to match this observation. + */ + UINT8 pduType; ++ if (!type) ++ return FALSE; ++ if (Stream_GetRemainingLength(s) < 6) ++ return FALSE; + Stream_Read_UINT8(s, pduType); /* pduTypeFlow */ + *type = pduType; + Stream_Seek_UINT8(s); /* pad8bits */ + Stream_Seek_UINT8(s); /* flowIdentifier */ + Stream_Seek_UINT8(s); /* flowNumber */ + Stream_Seek_UINT16(s); /* pduSource */ ++ return TRUE; + } + + /** +diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h +index 9df6c0a..24d062d 100644 +--- a/libfreerdp/core/rdp.h ++++ b/libfreerdp/core/rdp.h +@@ -221,7 +221,7 @@ FREERDP_LOCAL int rdp_recv_message_channel_pdu(rdpRdp* rdp, wStream* s, + + FREERDP_LOCAL int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s); + +-FREERDP_LOCAL void rdp_read_flow_control_pdu(wStream* s, UINT16* type); ++FREERDP_LOCAL BOOL rdp_read_flow_control_pdu(wStream* s, UINT16* type); + + FREERDP_LOCAL BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, + const rdpMonitor* monitorDefArray); diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,11 @@ +--- a/libfreerdp/core/autodetect.c ++++ b/libfreerdp/core/autodetect.c +@@ -454,6 +454,8 @@ static BOOL autodetect_recv_bandwidth_measure_results(rdpRdp* rdp, wStream* s, + return FALSE; + + WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Results PDU"); ++ if (Stream_GetRemainingLength(s) < 8) ++ return -1; + Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureTimeDelta); /* timeDelta (4 bytes) */ + Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureByteCount); /* byteCount (4 bytes) */ + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,28 @@ +--- a/libfreerdp/core/update.c ++++ b/libfreerdp/core/update.c +@@ -292,13 +292,13 @@ fail: + return NULL; + } + +-static void update_read_synchronize(rdpUpdate* update, wStream* s) ++static BOOL update_read_synchronize(rdpUpdate* update, wStream* s) + { +- Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ + /** + * The Synchronize Update is an artifact from the + * T.128 protocol and should be ignored. + */ ++ return Stream_SafeSeek(s, 2); /* pad2Octets (2 bytes) */ + } + + static BOOL update_read_play_sound(wStream* s, PLAY_SOUND_UPDATE* play_sound) +@@ -676,7 +676,8 @@ BOOL update_recv(rdpUpdate* update, wStream* s) + break; + + case UPDATE_TYPE_SYNCHRONIZE: +- update_read_synchronize(update, s); ++ if (!update_read_synchronize(update, s)) ++ return FALSE; + rc = IFCALLRESULT(TRUE, update->Synchronize, context); + break; + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,12 @@ +--- a/libfreerdp/core/update.c ++++ b/libfreerdp/core/update.c +@@ -109,6 +109,9 @@ static BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, + { + if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR)) + { ++ if (Stream_GetRemainingLength(s) < 8) ++ return FALSE; ++ + Stream_Read_UINT16(s, + bitmapData->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ + Stream_Read_UINT16(s, diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,16 @@ +--- a/libfreerdp/core/capabilities.c ++++ b/libfreerdp/core/capabilities.c +@@ -1379,10 +1379,10 @@ static BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) + static BOOL rdp_read_font_capability_set(wStream* s, UINT16 length, + rdpSettings* settings) + { +- if (length > 4) ++ if (length > 5) + Stream_Seek_UINT16(s); /* fontSupportFlags (2 bytes) */ + +- if (length > 6) ++ if (length > 7) + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ + + return TRUE; + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0008-Fixed-6013-Check-new-length-is-0.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0008-Fixed-6013-Check-new-length-is-0.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0008-Fixed-6013-Check-new-length-is-0.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0008-Fixed-6013-Check-new-length-is-0.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,11 @@ +--- a/libfreerdp/core/orders.c ++++ b/libfreerdp/core/orders.c +@@ -2237,7 +2237,7 @@ static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* updat + Stream_Read_UINT16(s, bitmapData->height); /* height (2 bytes) */ + Stream_Read_UINT32(s, new_len); /* length (4 bytes) */ + +- if (Stream_GetRemainingLength(s) < new_len) ++ if ((new_len == 0) || (Stream_GetRemainingLength(s) < new_len)) + goto fail; + + new_data = (BYTE*) realloc(bitmapData->data, new_len); diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0009-Fix-6010-Check-length-in-read_icon_info.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0009-Fix-6010-Check-length-in-read_icon_info.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0009-Fix-6010-Check-length-in-read_icon_info.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0009-Fix-6010-Check-length-in-read_icon_info.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,43 @@ +--- a/libfreerdp/core/window.c ++++ b/libfreerdp/core/window.c +@@ -110,9 +110,6 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) + Stream_Read_UINT16(s, iconInfo->cbBitsMask); /* cbBitsMask (2 bytes) */ + Stream_Read_UINT16(s, iconInfo->cbBitsColor); /* cbBitsColor (2 bytes) */ + +- if (Stream_GetRemainingLength(s) < iconInfo->cbBitsMask + iconInfo->cbBitsColor) +- return FALSE; +- + /* bitsMask */ + newBitMask = (BYTE*) realloc(iconInfo->bitsMask, iconInfo->cbBitsMask); + +@@ -124,6 +121,8 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) + } + + iconInfo->bitsMask = newBitMask; ++ if (Stream_GetRemainingLength(s) < iconInfo->cbBitsMask) ++ return FALSE; + Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask); + + /* colorTable */ +@@ -158,7 +157,11 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) + } + + if (iconInfo->colorTable) ++ { ++ if (Stream_GetRemainingLength(s) < iconInfo->cbColorTable) ++ return FALSE; + Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable); ++ } + + /* bitsColor */ + newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor); +@@ -171,6 +174,8 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) + } + + iconInfo->bitsColor = newBitMask; ++ if (Stream_GetRemainingLength(s) < iconInfo->cbBitsColor) ++ return FALSE; + Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor); + return TRUE; + } + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,94 @@ +--- a/libfreerdp/core/gcc.c ++++ b/libfreerdp/core/gcc.c +@@ -494,18 +494,27 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) + + while (offset < length) + { +- holdp = Stream_Pointer(s); ++ size_t rest; ++ wStream sub; + + if (!gcc_read_user_data_header(s, &type, &blockLength)) + { + WLog_ERR(TAG, "gcc_read_server_data_blocks: gcc_read_user_data_header failed"); + return FALSE; + } ++ holdp = Stream_Pointer(s); ++ Stream_StaticInit(&sub, holdp, blockLength - 4); ++ if (!Stream_SafeSeek(s, blockLength - 4)) ++ { ++ WLog_ERR(TAG, "gcc_read_server_data_blocks: stream too short"); ++ return FALSE; ++ } ++ offset += blockLength; + + switch (type) + { + case SC_CORE: +- if (!gcc_read_server_core_data(s, mcs)) ++ if (!gcc_read_server_core_data(&sub, mcs)) + { + WLog_ERR(TAG, "gcc_read_server_data_blocks: gcc_read_server_core_data failed"); + return FALSE; +@@ -514,7 +523,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) + break; + + case SC_SECURITY: +- if (!gcc_read_server_security_data(s, mcs)) ++ if (!gcc_read_server_security_data(&sub, mcs)) + { + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_security_data failed"); +@@ -524,7 +533,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) + break; + + case SC_NET: +- if (!gcc_read_server_network_data(s, mcs)) ++ if (!gcc_read_server_network_data(&sub, mcs)) + { + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_network_data failed"); +@@ -534,7 +543,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) + break; + + case SC_MCS_MSGCHANNEL: +- if (!gcc_read_server_message_channel_data(s, mcs)) ++ if (!gcc_read_server_message_channel_data(&sub, mcs)) + { + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed"); +@@ -544,7 +553,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) + break; + + case SC_MULTITRANSPORT: +- if (!gcc_read_server_multitransport_channel_data(s, mcs)) ++ if (!gcc_read_server_multitransport_channel_data(&sub, mcs)) + { + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_multitransport_channel_data failed"); +@@ -558,8 +567,13 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) + break; + } + +- offset += blockLength; +- Stream_SetPointer(s, holdp + blockLength); ++ rest = Stream_GetRemainingLength(&sub); ++ if (rest > 0) ++ { ++ WLog_WARN( ++ TAG, "gcc_read_server_data_blocks: ignoring %" PRIuz " bytes with type=%" PRIu16 "", ++ rest, type); ++ } + } + + return TRUE; +@@ -583,7 +597,7 @@ BOOL gcc_read_user_data_header(wStream* s, UINT16* type, UINT16* length) + Stream_Read_UINT16(s, *type); /* type */ + Stream_Read_UINT16(s, *length); /* length */ + +- if (Stream_GetRemainingLength(s) < (size_t)(*length - 4)) ++ if ((*length < 4) || (Stream_GetRemainingLength(s) < (size_t)(*length - 4))) + return FALSE; + + return TRUE; + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0011-Fixed-Stream_-macros-bracing-arguments.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0011-Fixed-Stream_-macros-bracing-arguments.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0011-Fixed-Stream_-macros-bracing-arguments.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0011-Fixed-Stream_-macros-bracing-arguments.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,109 @@ +--- a/winpr/include/winpr/stream.h ++++ b/winpr/include/winpr/stream.h +@@ -52,7 +52,7 @@ WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size); + WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size); + + WINPR_API wStream* Stream_New(BYTE* buffer, size_t size); +-WINPR_API void Stream_StaticInit(wStream *s, BYTE *buffer, size_t size); ++WINPR_API void Stream_StaticInit(wStream* s, BYTE* buffer, size_t size); + WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer); + + static INLINE void Stream_Seek(wStream* s, size_t _offset) +@@ -66,60 +66,60 @@ static INLINE void Stream_Rewind(wStream* s, size_t _offset) + } + + #define _stream_read_n8(_t, _s, _v, _p) do { \ +- _v = \ +- (_t)(*_s->pointer); \ ++ (_v) = \ ++ (_t)(*(_s)->pointer); \ + if (_p) Stream_Seek(_s, sizeof(_t)); } while (0) + + #define _stream_read_n16_le(_t, _s, _v, _p) do { \ +- _v = \ +- (_t)(*_s->pointer) + \ +- (_t)(((_t)(*(_s->pointer + 1))) << 8); \ ++ (_v) = \ ++ (_t)(*(_s)->pointer) + \ ++ (_t)(((_t)(*((_s)->pointer + 1))) << 8); \ + if (_p) Stream_Seek(_s, sizeof(_t)); } while (0) + + #define _stream_read_n16_be(_t, _s, _v, _p) do { \ +- _v = \ +- (_t)(((_t)(*_s->pointer)) << 8) + \ +- (_t)(*(_s->pointer + 1)); \ ++ (_v) = \ ++ (_t)(((_t)(*(_s)->pointer)) << 8) + \ ++ (_t)(*((_s)->pointer + 1)); \ + if (_p) Stream_Seek(_s, sizeof(_t)); } while (0) + + #define _stream_read_n32_le(_t, _s, _v, _p) do { \ +- _v = \ +- (_t)(*_s->pointer) + \ +- (((_t)(*(_s->pointer + 1))) << 8) + \ +- (((_t)(*(_s->pointer + 2))) << 16) + \ +- (((_t)(*(_s->pointer + 3))) << 24); \ ++ (_v) = \ ++ (_t)(*(_s)->pointer) + \ ++ (((_t)(*((_s)->pointer + 1))) << 8) + \ ++ (((_t)(*((_s)->pointer + 2))) << 16) + \ ++ (((_t)(*((_s)->pointer + 3))) << 24); \ + if (_p) Stream_Seek(_s, sizeof(_t)); } while (0) + + #define _stream_read_n32_be(_t, _s, _v, _p) do { \ +- _v = \ +- (((_t)(*(_s->pointer))) << 24) + \ +- (((_t)(*(_s->pointer + 1))) << 16) + \ +- (((_t)(*(_s->pointer + 2))) << 8) + \ +- (((_t)(*(_s->pointer + 3)))); \ ++ (_v) = \ ++ (((_t)(*((_s)->pointer))) << 24) + \ ++ (((_t)(*((_s)->pointer + 1))) << 16) + \ ++ (((_t)(*((_s)->pointer + 2))) << 8) + \ ++ (((_t)(*((_s)->pointer + 3)))); \ + if (_p) Stream_Seek(_s, sizeof(_t)); } while (0) + + #define _stream_read_n64_le(_t, _s, _v, _p) do { \ +- _v = \ +- (_t)(*_s->pointer) + \ +- (((_t)(*(_s->pointer + 1))) << 8) + \ +- (((_t)(*(_s->pointer + 2))) << 16) + \ +- (((_t)(*(_s->pointer + 3))) << 24) + \ +- (((_t)(*(_s->pointer + 4))) << 32) + \ +- (((_t)(*(_s->pointer + 5))) << 40) + \ +- (((_t)(*(_s->pointer + 6))) << 48) + \ +- (((_t)(*(_s->pointer + 7))) << 56); \ ++ (_v) = \ ++ (_t)(*(_s)->pointer) + \ ++ (((_t)(*((_s)->pointer + 1))) << 8) + \ ++ (((_t)(*((_s)->pointer + 2))) << 16) + \ ++ (((_t)(*((_s)->pointer + 3))) << 24) + \ ++ (((_t)(*((_s)->pointer + 4))) << 32) + \ ++ (((_t)(*((_s)->pointer + 5))) << 40) + \ ++ (((_t)(*((_s)->pointer + 6))) << 48) + \ ++ (((_t)(*((_s)->pointer + 7))) << 56); \ + if (_p) Stream_Seek(_s, sizeof(_t)); } while (0) + + #define _stream_read_n64_be(_t, _s, _v, _p) do { \ +- _v = \ +- (((_t)(*(_s->pointer))) << 56) + \ +- (((_t)(*(_s->pointer + 1))) << 48) + \ +- (((_t)(*(_s->pointer + 2))) << 40) + \ +- (((_t)(*(_s->pointer + 3))) << 32) + \ +- (((_t)(*(_s->pointer + 4))) << 24) + \ +- (((_t)(*(_s->pointer + 5))) << 16) + \ +- (((_t)(*(_s->pointer + 6))) << 8) + \ +- (((_t)(*(_s->pointer + 7)))); \ ++ (_v) = \ ++ (((_t)(*((_s)->pointer))) << 56) + \ ++ (((_t)(*((_s)->pointer + 1))) << 48) + \ ++ (((_t)(*((_s)->pointer + 2))) << 40) + \ ++ (((_t)(*((_s)->pointer + 3))) << 32) + \ ++ (((_t)(*((_s)->pointer + 4))) << 24) + \ ++ (((_t)(*((_s)->pointer + 5))) << 16) + \ ++ (((_t)(*((_s)->pointer + 6))) << 8) + \ ++ (((_t)(*((_s)->pointer + 7)))); \ + if (_p) Stream_Seek(_s, sizeof(_t)); } while (0) + + #define Stream_Read_UINT8(_s, _v) _stream_read_n8(UINT8, _s, _v, TRUE) + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0012-Use-safe-seek-for-capability-parsing.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0012-Use-safe-seek-for-capability-parsing.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0012-Use-safe-seek-for-capability-parsing.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0012-Use-safe-seek-for-capability-parsing.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,1835 @@ +--- a/libfreerdp/core/capabilities.c ++++ b/libfreerdp/core/capabilities.c +@@ -125,11 +125,16 @@ static const GUID CODEC_GUID_JPEG = + }; + #endif + +-static void rdp_read_capability_set_header(wStream* s, UINT16* length, ++static BOOL rdp_read_capability_set_header(wStream* s, UINT16* length, + UINT16* type) + { ++ if (Stream_GetRemainingLength(s) < 4) ++ return FALSE; + Stream_Read_UINT16(s, *type); /* capabilitySetType */ + Stream_Read_UINT16(s, *length); /* lengthCapability */ ++ if (*length < 4) ++ return FALSE; ++ return TRUE; + } + + static void rdp_write_capability_set_header(wStream* s, UINT16 length, +@@ -166,14 +171,13 @@ static void rdp_capability_set_finish(wStream* s, int header, UINT16 type) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_general_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_general_capability_set(wStream* s, rdpSettings* settings) + { + UINT16 extraFlags; + BYTE refreshRectSupport; + BYTE suppressOutputSupport; + +- if (length < 24) ++ if (Stream_GetRemainingLength(s) < 20) + return FALSE; + + if (settings->ServerMode) +@@ -272,7 +276,7 @@ static BOOL rdp_write_general_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_general_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_general_capability_set(wStream* s) + { + UINT16 osMajorType; + UINT16 osMinorType; +@@ -286,10 +290,10 @@ static BOOL rdp_print_general_capability_set(wStream* s, UINT16 length) + BYTE refreshRectSupport; + BYTE suppressOutputSupport; + +- if (length < 24) ++ if (Stream_GetRemainingLength(s) < 20) + return FALSE; + +- WLog_INFO(TAG, "GeneralCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "GeneralCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + Stream_Read_UINT16(s, osMajorType); /* osMajorType (2 bytes) */ + Stream_Read_UINT16(s, osMinorType); /* osMinorType (2 bytes) */ + Stream_Read_UINT16(s, protocolVersion); /* protocolVersion (2 bytes) */ +@@ -324,8 +328,7 @@ static BOOL rdp_print_general_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_bitmap_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_bitmap_capability_set(wStream* s, rdpSettings* settings) + { + BYTE drawingFlags; + UINT16 desktopWidth; +@@ -333,7 +336,7 @@ static BOOL rdp_read_bitmap_capability_set(wStream* s, UINT16 length, + UINT16 desktopResizeFlag; + UINT16 preferredBitsPerPixel; + +- if (length < 28) ++ if (Stream_GetRemainingLength(s) < 24) + return FALSE; + + Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ +@@ -438,7 +441,7 @@ static BOOL rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_bitmap_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_bitmap_capability_set(wStream* s) + { + UINT16 preferredBitsPerPixel; + UINT16 receive1BitPerPixel; +@@ -453,9 +456,9 @@ static BOOL rdp_print_bitmap_capability_set(wStream* s, UINT16 length) + BYTE drawingFlags; + UINT16 multipleRectangleSupport; + UINT16 pad2OctetsB; +- WLog_INFO(TAG, "BitmapCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "BitmapCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 28) ++ if (Stream_GetRemainingLength(s) < 24) + return FALSE; + + Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ +@@ -496,8 +499,7 @@ static BOOL rdp_print_bitmap_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_order_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_order_capability_set(wStream* s, rdpSettings* settings) + { + int i; + UINT16 orderFlags; +@@ -506,7 +508,7 @@ static BOOL rdp_read_order_capability_set(wStream* s, UINT16 length, + BOOL BitmapCacheV3Enabled = FALSE; + BOOL FrameMarkerCommandEnabled = FALSE; + +- if (length < 88) ++ if (Stream_GetRemainingLength(s) < 84) + return FALSE; + + Stream_Seek(s, 16); /* terminalDescriptor (16 bytes) */ +@@ -614,7 +616,7 @@ static BOOL rdp_write_order_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_order_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_order_capability_set(wStream* s) + { + BYTE terminalDescriptor[16]; + UINT32 pad4OctetsA; +@@ -633,9 +635,9 @@ static BOOL rdp_print_order_capability_set(wStream* s, UINT16 length) + UINT16 pad2OctetsD; + UINT16 textANSICodePage; + UINT16 pad2OctetsE; +- WLog_INFO(TAG, "OrderCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "OrderCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 88) ++ if (Stream_GetRemainingLength(s) < 84) + return FALSE; + + Stream_Read(s, terminalDescriptor, 16); /* terminalDescriptor (16 bytes) */ +@@ -716,10 +718,9 @@ static BOOL rdp_print_order_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_bitmap_cache_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_bitmap_cache_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 40) ++ if (Stream_GetRemainingLength(s) < 36) + return FALSE; + + Stream_Seek_UINT32(s); /* pad1 (4 bytes) */ +@@ -776,7 +777,7 @@ static BOOL rdp_write_bitmap_cache_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_bitmap_cache_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_bitmap_cache_capability_set(wStream* s) + { + UINT32 pad1, pad2, pad3; + UINT32 pad4, pad5, pad6; +@@ -786,9 +787,9 @@ static BOOL rdp_print_bitmap_cache_capability_set(wStream* s, UINT16 length) + UINT16 Cache1MaximumCellSize; + UINT16 Cache2Entries; + UINT16 Cache2MaximumCellSize; +- WLog_INFO(TAG, "BitmapCacheCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "BitmapCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 40) ++ if (Stream_GetRemainingLength(s) < 36) + return FALSE; + + Stream_Read_UINT32(s, pad1); /* pad1 (4 bytes) */ +@@ -827,10 +828,9 @@ static BOOL rdp_print_bitmap_cache_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_control_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_control_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Seek_UINT16(s); /* controlFlags (2 bytes) */ +@@ -864,15 +864,15 @@ static BOOL rdp_write_control_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_control_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_control_capability_set(wStream* s) + { + UINT16 controlFlags; + UINT16 remoteDetachFlag; + UINT16 controlInterest; + UINT16 detachInterest; +- WLog_INFO(TAG, "ControlCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "ControlCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT16(s, controlFlags); /* controlFlags (2 bytes) */ +@@ -895,10 +895,9 @@ static BOOL rdp_print_control_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_window_activation_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_window_activation_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Seek_UINT16(s); /* helpKeyFlag (2 bytes) */ +@@ -933,16 +932,16 @@ static BOOL rdp_write_window_activation_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_window_activation_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_window_activation_capability_set(wStream* s) + { + UINT16 helpKeyFlag; + UINT16 helpKeyIndexFlag; + UINT16 helpExtendedKeyFlag; + UINT16 windowManagerKeyFlag; +- WLog_INFO(TAG, "WindowActivationCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "WindowActivationCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT16(s, helpKeyFlag); /* helpKeyFlag (2 bytes) */ +@@ -965,14 +964,13 @@ static BOOL rdp_print_window_activation_capability_set(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_pointer_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_pointer_capability_set(wStream* s, rdpSettings* settings) + { + UINT16 colorPointerFlag; + UINT16 colorPointerCacheSize; + UINT16 pointerCacheSize; + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ +@@ -980,7 +978,7 @@ static BOOL rdp_read_pointer_capability_set(wStream* s, UINT16 length, + colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + + /* pointerCacheSize is optional */ +- if (length >= 10) ++ if (Stream_GetRemainingLength(s) >= 2) + Stream_Read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ + else + pointerCacheSize = 0; +@@ -1026,16 +1024,16 @@ static BOOL rdp_write_pointer_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_pointer_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_pointer_capability_set(wStream* s) + { + UINT16 colorPointerFlag; + UINT16 colorPointerCacheSize; + UINT16 pointerCacheSize; + +- if (length < 10) ++ if (Stream_GetRemainingLength(s) < 6) + return FALSE; + +- WLog_INFO(TAG, "PointerCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "PointerCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ + Stream_Read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + Stream_Read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ +@@ -1054,10 +1052,9 @@ static BOOL rdp_print_pointer_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_share_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_share_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Seek_UINT16(s); /* nodeId (2 bytes) */ +@@ -1089,13 +1086,13 @@ static BOOL rdp_write_share_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_share_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_share_capability_set(wStream* s) + { + UINT16 nodeId; + UINT16 pad2Octets; +- WLog_INFO(TAG, "ShareCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "ShareCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT16(s, nodeId); /* nodeId (2 bytes) */ +@@ -1114,10 +1111,9 @@ static BOOL rdp_print_share_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_color_cache_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_color_cache_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Seek_UINT16(s); /* colorTableCacheSize (2 bytes) */ +@@ -1148,13 +1144,13 @@ static BOOL rdp_write_color_cache_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_color_cache_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_color_cache_capability_set(wStream* s) + { + UINT16 colorTableCacheSize; + UINT16 pad2Octets; +- WLog_INFO(TAG, "ColorCacheCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "ColorCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT16(s, colorTableCacheSize); /* colorTableCacheSize (2 bytes) */ +@@ -1173,12 +1169,11 @@ static BOOL rdp_print_color_cache_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_sound_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_sound_capability_set(wStream* s, rdpSettings* settings) + { + UINT16 soundFlags; + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ +@@ -1211,13 +1206,13 @@ static BOOL rdp_write_sound_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_sound_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_sound_capability_set(wStream* s) + { + UINT16 soundFlags; + UINT16 pad2OctetsA; +- WLog_INFO(TAG, "SoundCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "SoundCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ +@@ -1236,12 +1231,11 @@ static BOOL rdp_print_sound_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_input_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_input_capability_set(wStream* s, rdpSettings* settings) + { + UINT16 inputFlags; + +- if (length < 88) ++ if (Stream_GetRemainingLength(s) < 84) + return FALSE; + + Stream_Read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ +@@ -1338,7 +1332,7 @@ static BOOL rdp_write_input_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_input_capability_set(wStream* s) + { + UINT16 inputFlags; + UINT16 pad2OctetsA; +@@ -1346,9 +1340,9 @@ static BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) + UINT32 keyboardType; + UINT32 keyboardSubType; + UINT32 keyboardFunctionKey; +- WLog_INFO(TAG, "InputCapabilitySet (length %"PRIu16")", length); ++ WLog_INFO(TAG, "InputCapabilitySet (length %" PRIuz ")", Stream_GetRemainingLength(s)); + +- if (length < 88) ++ if (Stream_GetRemainingLength(s) < 84) + return FALSE; + + Stream_Read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ +@@ -1376,13 +1370,12 @@ static BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_font_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_font_capability_set(wStream* s, rdpSettings* settings) + { +- if (length > 5) ++ if (Stream_GetRemainingLength(s) >= 2) + Stream_Seek_UINT16(s); /* fontSupportFlags (2 bytes) */ + +- if (length > 7) ++ if (Stream_GetRemainingLength(s) >= 2) + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ + + return TRUE; +@@ -1410,16 +1403,16 @@ static BOOL rdp_write_font_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_font_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_font_capability_set(wStream* s) + { + UINT16 fontSupportFlags = 0; + UINT16 pad2Octets = 0; +- WLog_INFO(TAG, "FontCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "FontCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length > 4) ++ if (Stream_GetRemainingLength(s) >= 2) + Stream_Read_UINT16(s, fontSupportFlags); /* fontSupportFlags (2 bytes) */ + +- if (length > 6) ++ if (Stream_GetRemainingLength(s) >= 2) + Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ + + WLog_INFO(TAG, "\tfontSupportFlags: 0x%04"PRIX16"", fontSupportFlags); +@@ -1436,14 +1429,9 @@ static BOOL rdp_print_font_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_brush_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_brush_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 8) +- return FALSE; +- +- Stream_Seek_UINT32(s); /* brushSupportLevel (4 bytes) */ +- return TRUE; ++ return Stream_SafeSeek(s, 4); /* brushSupportLevel (4 bytes) */ + } + + /** +@@ -1467,12 +1455,12 @@ static BOOL rdp_write_brush_capability_set(wStream* s, rdpSettings* settings) + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_brush_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_brush_capability_set(wStream* s) + { + UINT32 brushSupportLevel; +- WLog_INFO(TAG, "BrushCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "BrushCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, brushSupportLevel); /* brushSupportLevel (4 bytes) */ +@@ -1513,10 +1501,9 @@ static void rdp_write_cache_definition(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_glyph_cache_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_glyph_cache_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 52) ++ if (Stream_GetRemainingLength(s) < 48) + return FALSE; + + /* glyphCache (40 bytes) */ +@@ -1571,15 +1558,15 @@ static BOOL rdp_write_glyph_cache_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_glyph_cache_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_glyph_cache_capability_set(wStream* s) + { + GLYPH_CACHE_DEFINITION glyphCache[10]; + GLYPH_CACHE_DEFINITION fragCache; + UINT16 glyphSupportLevel; + UINT16 pad2Octets; +- WLog_INFO(TAG, "GlyphCacheCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "GlyphCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 52) ++ if (Stream_GetRemainingLength(s) < 48) + return FALSE; + + /* glyphCache (40 bytes) */ +@@ -1632,12 +1619,11 @@ static BOOL rdp_print_glyph_cache_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wStream* s, +- UINT16 length, rdpSettings* settings) ++static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wStream* s, rdpSettings* settings) + { + UINT32 offscreenSupportLevel; + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ +@@ -1679,15 +1665,15 @@ static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s) + { + UINT32 offscreenSupportLevel; + UINT16 offscreenCacheSize; + UINT16 offscreenCacheEntries; +- WLog_INFO(TAG, "OffscreenBitmapCacheCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "OffscreenBitmapCacheCapabilitySet (length %" PRIuz "):", ++ Stream_GetRemainingLength(s)); + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ +@@ -1708,12 +1694,11 @@ static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_bitmap_cache_host_support_capability_set(wStream* s, +- UINT16 length, rdpSettings* settings) ++static BOOL rdp_read_bitmap_cache_host_support_capability_set(wStream* s, rdpSettings* settings) + { + BYTE cacheVersion; + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT8(s, cacheVersion); /* cacheVersion (1 byte) */ +@@ -1750,15 +1735,15 @@ static BOOL rdp_write_bitmap_cache_host_support_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_bitmap_cache_host_support_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_bitmap_cache_host_support_capability_set(wStream* s) + { + BYTE cacheVersion; + BYTE pad1; + UINT16 pad2; +- WLog_INFO(TAG, "BitmapCacheHostSupportCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "BitmapCacheHostSupportCapabilitySet (length %" PRIuz "):", ++ Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT8(s, cacheVersion); /* cacheVersion (1 byte) */ +@@ -1803,10 +1788,9 @@ static void rdp_write_bitmap_cache_cell_info(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_bitmap_cache_v2_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_bitmap_cache_v2_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 40) ++ if (Stream_GetRemainingLength(s) < 36) + return FALSE; + + Stream_Seek_UINT16(s); /* cacheFlags (2 bytes) */ +@@ -1863,15 +1847,15 @@ static BOOL rdp_write_bitmap_cache_v2_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s) + { + UINT16 cacheFlags; + BYTE pad2; + BYTE numCellCaches; + BITMAP_CACHE_V2_CELL_INFO bitmapCacheV2CellInfo[5]; +- WLog_INFO(TAG, "BitmapCacheV2CapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "BitmapCacheV2CapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 40) ++ if (Stream_GetRemainingLength(s) < 36) + return FALSE; + + Stream_Read_UINT16(s, cacheFlags); /* cacheFlags (2 bytes) */ +@@ -1908,18 +1892,17 @@ static BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_virtual_channel_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_virtual_channel_capability_set(wStream* s, rdpSettings* settings) + { + UINT32 flags; + UINT32 VCChunkSize; + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, flags); /* flags (4 bytes) */ + +- if (length > 8) ++ if (Stream_GetRemainingLength(s) >= 4) + Stream_Read_UINT32(s, VCChunkSize); /* VCChunkSize (4 bytes) */ + else + VCChunkSize = 1600; +@@ -1956,18 +1939,19 @@ static BOOL rdp_write_virtual_channel_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_virtual_channel_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_virtual_channel_capability_set(wStream* s) + { + UINT32 flags; + UINT32 VCChunkSize; +- WLog_INFO(TAG, "VirtualChannelCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "VirtualChannelCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, flags); /* flags (4 bytes) */ + +- if (length > 8) ++ if (Stream_GetRemainingLength(s) >= 4) + Stream_Read_UINT32(s, VCChunkSize); /* VCChunkSize (4 bytes) */ + else + VCChunkSize = 1600; +@@ -1986,12 +1970,11 @@ static BOOL rdp_print_virtual_channel_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_draw_nine_grid_cache_capability_set(wStream* s, +- UINT16 length, rdpSettings* settings) ++static BOOL rdp_read_draw_nine_grid_cache_capability_set(wStream* s, rdpSettings* settings) + { + UINT32 drawNineGridSupportLevel; + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ +@@ -2061,15 +2044,15 @@ static void rdp_write_gdiplus_image_cache_properties(wStream* s, UINT16 oiccs, + + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s) + { + UINT32 drawNineGridSupportLevel; + UINT16 DrawNineGridCacheSize; + UINT16 DrawNineGridCacheEntries; +- WLog_INFO(TAG, "DrawNineGridCacheCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "DrawNineGridCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ +@@ -2087,13 +2070,12 @@ static BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_draw_gdiplus_cache_capability_set(wStream* s, +- UINT16 length, rdpSettings* settings) ++static BOOL rdp_read_draw_gdiplus_cache_capability_set(wStream* s, rdpSettings* settings) + { + UINT32 drawGDIPlusSupportLevel; + UINT32 drawGdiplusCacheLevel; + +- if (length < 40) ++ if (Stream_GetRemainingLength(s) < 36) + return FALSE; + + Stream_Read_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ +@@ -2145,15 +2127,15 @@ static BOOL rdp_write_draw_gdiplus_cache_capability_set(wStream* s, rdpSettings* + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_draw_gdiplus_cache_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_draw_gdiplus_cache_capability_set(wStream* s) + { + UINT32 drawGdiPlusSupportLevel; + UINT32 GdipVersion; + UINT32 drawGdiplusCacheLevel; +- WLog_INFO(TAG, "DrawGdiPlusCacheCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "DrawGdiPlusCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 40) ++ if (Stream_GetRemainingLength(s) < 36) + return FALSE; + + Stream_Read_UINT32(s, drawGdiPlusSupportLevel); /* drawGdiPlusSupportLevel (4 bytes) */ +@@ -2174,12 +2156,11 @@ static BOOL rdp_print_draw_gdiplus_cache_capability_set(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_remote_programs_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_remote_programs_capability_set(wStream* s, rdpSettings* settings) + { + UINT32 railSupportLevel; + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ +@@ -2224,12 +2205,13 @@ static BOOL rdp_write_remote_programs_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_remote_programs_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_remote_programs_capability_set(wStream* s) + { + UINT32 railSupportLevel; +- WLog_INFO(TAG, "RemoteProgramsCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "RemoteProgramsCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ +@@ -2246,10 +2228,9 @@ static BOOL rdp_print_remote_programs_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_window_list_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_window_list_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 11) ++ if (Stream_GetRemainingLength(s) < 7) + return FALSE; + + Stream_Read_UINT32(s, settings->RemoteWndSupportLevel); /* wndSupportLevel (4 bytes) */ +@@ -2281,14 +2262,14 @@ static BOOL rdp_write_window_list_capability_set(wStream* s, rdpSettings* settin + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_window_list_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_window_list_capability_set(wStream* s) + { + UINT32 wndSupportLevel; + BYTE numIconCaches; + UINT16 numIconCacheEntries; +- WLog_INFO(TAG, "WindowListCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "WindowListCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 11) ++ if (Stream_GetRemainingLength(s) < 7) + return FALSE; + + Stream_Read_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ +@@ -2309,10 +2290,9 @@ static BOOL rdp_print_window_list_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_desktop_composition_capability_set(wStream* s, +- UINT16 length, rdpSettings* settings) ++static BOOL rdp_read_desktop_composition_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 6) ++ if (Stream_GetRemainingLength(s) < 2) + return FALSE; + + Stream_Seek_UINT16(s); /* compDeskSupportLevel (2 bytes) */ +@@ -2344,13 +2324,13 @@ static BOOL rdp_write_desktop_composition_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_desktop_composition_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_desktop_composition_capability_set(wStream* s) + { + UINT16 compDeskSupportLevel; +- WLog_INFO(TAG, "DesktopCompositionCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "DesktopCompositionCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 6) ++ if (Stream_GetRemainingLength(s) < 2) + return FALSE; + + Stream_Read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ +@@ -2367,12 +2347,11 @@ static BOOL rdp_print_desktop_composition_capability_set(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_multifragment_update_capability_set(wStream* s, +- UINT16 length, rdpSettings* settings) ++static BOOL rdp_read_multifragment_update_capability_set(wStream* s, rdpSettings* settings) + { + UINT32 multifragMaxRequestSize; + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, multifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ +@@ -2472,13 +2451,13 @@ static BOOL rdp_write_multifragment_update_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_multifragment_update_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_multifragment_update_capability_set(wStream* s) + { + UINT32 maxRequestSize; +- WLog_INFO(TAG, "MultifragmentUpdateCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO( ++ TAG, "MultifragmentUpdateCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, maxRequestSize); /* maxRequestSize (4 bytes) */ +@@ -2495,12 +2474,11 @@ static BOOL rdp_print_multifragment_update_capability_set(wStream* s, + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_large_pointer_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_large_pointer_capability_set(wStream* s, rdpSettings* settings) + { + UINT16 largePointerSupportFlags; + +- if (length < 6) ++ if (Stream_GetRemainingLength(s) < 2) + return FALSE; + + Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ +@@ -2532,12 +2510,12 @@ static BOOL rdp_write_large_pointer_capability_set(wStream* s, rdpSettings* sett + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_large_pointer_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_large_pointer_capability_set(wStream* s) + { + UINT16 largePointerSupportFlags; +- WLog_INFO(TAG, "LargePointerCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "LargePointerCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 6) ++ if (Stream_GetRemainingLength(s) < 2) + return FALSE; + + Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ +@@ -2554,12 +2532,11 @@ static BOOL rdp_print_large_pointer_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_surface_commands_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_surface_commands_capability_set(wStream* s, rdpSettings* settings) + { + UINT32 cmdFlags; + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ +@@ -2599,13 +2576,14 @@ static BOOL rdp_write_surface_commands_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_surface_commands_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_surface_commands_capability_set(wStream* s) + { + UINT32 cmdFlags; + UINT32 reserved; +- WLog_INFO(TAG, "SurfaceCommandsCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "SurfaceCommandsCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 12) ++ if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ +@@ -2648,9 +2626,11 @@ static char* rdp_get_bitmap_codec_guid_name(const GUID* guid) + } + #endif + +-static void rdp_read_bitmap_codec_guid(wStream* s, GUID* guid) ++static BOOL rdp_read_bitmap_codec_guid(wStream* s, GUID* guid) + { + BYTE g[16]; ++ if (Stream_GetRemainingLength(s) < 16) ++ return FALSE; + Stream_Read(s, g, 16); + guid->Data1 = (g[3] << 24) | (g[2] << 16) | (g[1] << 8) | g[0]; + guid->Data2 = (g[5] << 8) | g[4]; +@@ -2663,6 +2643,7 @@ static void rdp_read_bitmap_codec_guid(wStream* s, GUID* guid) + guid->Data4[5] = g[13]; + guid->Data4[6] = g[14]; + guid->Data4[7] = g[15]; ++ return TRUE; + } + + static void rdp_write_bitmap_codec_guid(wStream* s, const GUID* guid) +@@ -2695,44 +2676,41 @@ static void rdp_write_bitmap_codec_guid(wStream* s, const GUID* guid) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* settings) + { + BYTE codecId; + GUID codecGuid; + RPC_STATUS rpc_status; + BYTE bitmapCodecCount; + UINT16 codecPropertiesLength; +- UINT16 remainingLength; ++ + BOOL guidNSCodec = FALSE; + BOOL guidRemoteFx = FALSE; + BOOL guidRemoteFxImage = FALSE; + +- if (length < 5) ++ if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ +- remainingLength = length - 5; + + while (bitmapCodecCount > 0) + { +- if (remainingLength < 19) ++ size_t rest; ++ wStream sub; ++ if (!rdp_read_bitmap_codec_guid(s, &codecGuid)) /* codecGuid (16 bytes) */ ++ return FALSE; ++ if (Stream_GetRemainingLength(s) < 3) + return FALSE; + +- rdp_read_bitmap_codec_guid(s, &codecGuid); /* codecGuid (16 bytes) */ + Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */ + Stream_Read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ +- remainingLength -= 19; + +- if (remainingLength < codecPropertiesLength) ++ Stream_StaticInit(&sub, Stream_Pointer(s), codecPropertiesLength); ++ if (!Stream_SafeSeek(s, codecPropertiesLength)) + return FALSE; + + if (settings->ServerMode) + { +- UINT32 beg; +- UINT32 end; +- beg = (UINT32) Stream_GetPosition(s); +- end = beg + codecPropertiesLength; + + if (UuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX, &rpc_status)) + { +@@ -2741,9 +2719,11 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, + UINT32 captureFlags; + guidRemoteFx = TRUE; + settings->RemoteFxCodecId = codecId; +- Stream_Read_UINT32(s, rfxPropsLength); /* length (4 bytes) */ +- Stream_Read_UINT32(s, captureFlags); /* captureFlags (4 bytes) */ +- Stream_Read_UINT32(s, rfxCapsLength); /* capsLength (4 bytes) */ ++ if (Stream_GetRemainingLength(&sub) < 12) ++ return FALSE; ++ Stream_Read_UINT32(&sub, rfxPropsLength); /* length (4 bytes) */ ++ Stream_Read_UINT32(&sub, captureFlags); /* captureFlags (4 bytes) */ ++ Stream_Read_UINT32(&sub, rfxCapsLength); /* capsLength (4 bytes) */ + settings->RemoteFxCaptureFlags = captureFlags; + settings->RemoteFxOnly = (captureFlags & CARDP_CAPS_CAPTURE_NON_CAC) ? TRUE : + FALSE; +@@ -2758,9 +2738,11 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, + UINT16 numIcaps; + UINT16 icapLen; + /* TS_RFX_CAPS */ +- Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */ +- Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */ +- Stream_Read_UINT16(s, numCapsets); /* numCapsets (2 bytes) */ ++ if (Stream_GetRemainingLength(&sub) < 21) ++ return FALSE; ++ Stream_Read_UINT16(&sub, blockType); /* blockType (2 bytes) */ ++ Stream_Read_UINT32(&sub, blockLen); /* blockLen (4 bytes) */ ++ Stream_Read_UINT16(&sub, numCapsets); /* numCapsets (2 bytes) */ + + if (blockType != 0xCBC0) + return FALSE; +@@ -2772,12 +2754,12 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, + return FALSE; + + /* TS_RFX_CAPSET */ +- Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */ +- Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */ +- Stream_Read_UINT8(s, rfxCodecId); /* codecId (1 byte) */ +- Stream_Read_UINT16(s, capsetType); /* capsetType (2 bytes) */ +- Stream_Read_UINT16(s, numIcaps); /* numIcaps (2 bytes) */ +- Stream_Read_UINT16(s, icapLen); /* icapLen (2 bytes) */ ++ Stream_Read_UINT16(&sub, blockType); /* blockType (2 bytes) */ ++ Stream_Read_UINT32(&sub, blockLen); /* blockLen (4 bytes) */ ++ Stream_Read_UINT8(&sub, rfxCodecId); /* codecId (1 byte) */ ++ Stream_Read_UINT16(&sub, capsetType); /* capsetType (2 bytes) */ ++ Stream_Read_UINT16(&sub, numIcaps); /* numIcaps (2 bytes) */ ++ Stream_Read_UINT16(&sub, icapLen); /* icapLen (2 bytes) */ + + if (blockType != 0xCBC1) + return FALSE; +@@ -2797,12 +2779,14 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, + BYTE transformBits; + BYTE entropyBits; + /* TS_RFX_ICAP */ +- Stream_Read_UINT16(s, version); /* version (2 bytes) */ +- Stream_Read_UINT16(s, tileSize); /* tileSize (2 bytes) */ +- Stream_Read_UINT8(s, codecFlags); /* flags (1 byte) */ +- Stream_Read_UINT8(s, colConvBits); /* colConvBits (1 byte) */ +- Stream_Read_UINT8(s, transformBits); /* transformBits (1 byte) */ +- Stream_Read_UINT8(s, entropyBits); /* entropyBits (1 byte) */ ++ if (Stream_GetRemainingLength(&sub) < 8) ++ return FALSE; ++ Stream_Read_UINT16(&sub, version); /* version (2 bytes) */ ++ Stream_Read_UINT16(&sub, tileSize); /* tileSize (2 bytes) */ ++ Stream_Read_UINT8(&sub, codecFlags); /* flags (1 byte) */ ++ Stream_Read_UINT8(&sub, colConvBits); /* colConvBits (1 byte) */ ++ Stream_Read_UINT8(&sub, transformBits); /* transformBits (1 byte) */ ++ Stream_Read_UINT8(&sub, entropyBits); /* entropyBits (1 byte) */ + + if (version == 0x0009) + { +@@ -2831,7 +2815,8 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, + { + /* Microsoft RDP servers ignore CODEC_GUID_IMAGE_REMOTEFX codec properties */ + guidRemoteFxImage = TRUE; +- Stream_Seek(s, codecPropertiesLength); /* codecProperties */ ++ if (!Stream_SafeSeek(&sub, codecPropertiesLength)) /* codecProperties */ ++ return FALSE; + } + else if (UuidEqual(&codecGuid, &CODEC_GUID_NSCODEC, &rpc_status)) + { +@@ -2840,9 +2825,11 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, + BYTE fAllowDynamicFidelity; + guidNSCodec = TRUE; + settings->NSCodecId = codecId; +- Stream_Read_UINT8(s, fAllowDynamicFidelity); /* fAllowDynamicFidelity (1 byte) */ +- Stream_Read_UINT8(s, fAllowSubsampling); /* fAllowSubsampling (1 byte) */ +- Stream_Read_UINT8(s, colorLossLevel); /* colorLossLevel (1 byte) */ ++ if (Stream_GetRemainingLength(&sub) < 3) ++ return FALSE; ++ Stream_Read_UINT8(&sub, fAllowDynamicFidelity); /* fAllowDynamicFidelity (1 byte) */ ++ Stream_Read_UINT8(&sub, fAllowSubsampling); /* fAllowSubsampling (1 byte) */ ++ Stream_Read_UINT8(&sub, colorLossLevel); /* colorLossLevel (1 byte) */ + + if (colorLossLevel < 1) + colorLossLevel = 1; +@@ -2857,28 +2844,30 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, + else if (UuidEqual(&codecGuid, &CODEC_GUID_IGNORE, &rpc_status)) + { + Stream_Seek(s, codecPropertiesLength); /* codecProperties */ ++ if (!Stream_SafeSeek(&sub, codecPropertiesLength)) /* codecProperties */ ++ return FALSE; + } + else + { +- Stream_Seek(s, codecPropertiesLength); /* codecProperties */ +- } +- +- if (Stream_GetPosition(s) != end) +- { +- WLog_ERR(TAG, +- "error while reading codec properties: actual offset: %"PRIuz" expected offset: %"PRIu32"", +- Stream_GetPosition(s), end); +- Stream_SetPosition(s, end); ++ if (!Stream_SafeSeek(&sub, codecPropertiesLength)) /* codecProperties */ ++ return FALSE; + } + +- remainingLength -= codecPropertiesLength; + } + else + { +- Stream_Seek(s, codecPropertiesLength); /* codecProperties */ +- remainingLength -= codecPropertiesLength; ++ if (!Stream_SafeSeek(&sub, codecPropertiesLength)) /* codecProperties */ ++ return FALSE; + } + ++ rest = Stream_GetRemainingLength(&sub); ++ if (rest > 0) ++ { ++ WLog_ERR(TAG, ++ "error while reading codec properties: actual size: %" PRIuz ++ " expected size: %" PRIu32 "", ++ rest + codecPropertiesLength, codecPropertiesLength); ++ } + bitmapCodecCount--; + } + +@@ -3158,28 +3147,26 @@ static BOOL rdp_write_bitmap_codecs_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) ++static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s) + { + GUID codecGuid; + BYTE bitmapCodecCount; +- BYTE codecId; + UINT16 codecPropertiesLength; +- UINT16 remainingLength; +- WLog_INFO(TAG, "BitmapCodecsCapabilitySet (length %"PRIu16"):", length); ++ BYTE codecId; ++ WLog_INFO(TAG, "BitmapCodecsCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 5) ++ if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ +- remainingLength = length - 5; + WLog_INFO(TAG, "\tbitmapCodecCount: %"PRIu8"", bitmapCodecCount); + + while (bitmapCodecCount > 0) + { +- if (remainingLength < 19) ++ if (!rdp_read_bitmap_codec_guid(s, &codecGuid)) /* codecGuid (16 bytes) */ + return FALSE; ++ if (Stream_GetRemainingLength(s) < 3) + +- rdp_read_bitmap_codec_guid(s, &codecGuid); /* codecGuid (16 bytes) */ + Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */ + WLog_INFO(TAG, "\tcodecGuid: 0x"); + rdp_print_bitmap_codec_guid(&codecGuid); +@@ -3188,13 +3175,10 @@ static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) + Stream_Read_UINT16(s, + codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ + WLog_INFO(TAG, "\tcodecPropertiesLength: %"PRIu16"", codecPropertiesLength); +- remainingLength -= 19; + +- if (remainingLength < codecPropertiesLength) ++ if (!Stream_SafeSeek(s, codecPropertiesLength)) /* codecProperties */ + return FALSE; + +- Stream_Seek(s, codecPropertiesLength); /* codecProperties */ +- remainingLength -= codecPropertiesLength; + bitmapCodecCount--; + } + +@@ -3209,10 +3193,9 @@ static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) + * @return if the operation completed successfully + */ + +-static BOOL rdp_read_frame_acknowledge_capability_set(wStream* s, UINT16 length, +- rdpSettings* settings) ++static BOOL rdp_read_frame_acknowledge_capability_set(wStream* s, rdpSettings* settings) + { +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + if (settings->ServerMode) +@@ -3248,13 +3231,13 @@ static BOOL rdp_write_frame_acknowledge_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_frame_acknowledge_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_frame_acknowledge_capability_set(wStream* s) + { + UINT32 frameAcknowledge; +- WLog_INFO(TAG, "FrameAcknowledgeCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, ++ "FrameAcknowledgeCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); + +- if (length < 8) ++ if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, frameAcknowledge); /* frameAcknowledge (4 bytes) */ +@@ -3263,12 +3246,11 @@ static BOOL rdp_print_frame_acknowledge_capability_set(wStream* s, + } + #endif + +-static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wStream* s, +- UINT16 length, rdpSettings* settings) ++static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wStream* s, rdpSettings* settings) + { + BYTE bitmapCacheV3CodecId; + +- if (length < 5) ++ if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ +@@ -3290,13 +3272,13 @@ static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wStream* s, + } + + #ifdef WITH_DEBUG_CAPABILITIES +-static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wStream* s, +- UINT16 length) ++static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wStream* s) + { + BYTE bitmapCacheV3CodecId; +- WLog_INFO(TAG, "BitmapCacheV3CodecIdCapabilitySet (length %"PRIu16"):", length); ++ WLog_INFO(TAG, "BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz "):", ++ Stream_GetRemainingLength(s)); + +- if (length < 5) ++ if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ +@@ -3309,193 +3291,191 @@ static BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, + { + UINT16 type; + UINT16 length; +- BYTE* bm, *em; + + while (numberCapabilities > 0) + { +- Stream_GetPointer(s, bm); +- rdp_read_capability_set_header(s, &length, &type); +- WLog_INFO(TAG, "%s ", receiving ? "Receiving" : "Sending"); +- em = bm + length; ++ size_t rest; ++ wStream sub; ++ if (!rdp_read_capability_set_header(s, &length, &type)) ++ return FALSE; + +- if (Stream_GetRemainingLength(s) < (size_t)(length - 4)) +- { +- WLog_ERR(TAG, "error processing stream"); ++ WLog_INFO(TAG, "%s ", receiving ? "Receiving" : "Sending"); ++ Stream_StaticInit(&sub, Stream_Pointer(s), length - 4); ++ if (!Stream_SafeSeek(s, length - 4)) + return FALSE; +- } + + switch (type) + { + case CAPSET_TYPE_GENERAL: +- if (!rdp_print_general_capability_set(s, length)) ++ if (!rdp_print_general_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP: +- if (!rdp_print_bitmap_capability_set(s, length)) ++ if (!rdp_print_bitmap_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_ORDER: +- if (!rdp_print_order_capability_set(s, length)) ++ if (!rdp_print_order_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CACHE: +- if (!rdp_print_bitmap_cache_capability_set(s, length)) ++ if (!rdp_print_bitmap_cache_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_CONTROL: +- if (!rdp_print_control_capability_set(s, length)) ++ if (!rdp_print_control_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_ACTIVATION: +- if (!rdp_print_window_activation_capability_set(s, length)) ++ if (!rdp_print_window_activation_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_POINTER: +- if (!rdp_print_pointer_capability_set(s, length)) ++ if (!rdp_print_pointer_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_SHARE: +- if (!rdp_print_share_capability_set(s, length)) ++ if (!rdp_print_share_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_COLOR_CACHE: +- if (!rdp_print_color_cache_capability_set(s, length)) ++ if (!rdp_print_color_cache_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_SOUND: +- if (!rdp_print_sound_capability_set(s, length)) ++ if (!rdp_print_sound_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_INPUT: +- if (!rdp_print_input_capability_set(s, length)) ++ if (!rdp_print_input_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_FONT: +- if (!rdp_print_font_capability_set(s, length)) ++ if (!rdp_print_font_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_BRUSH: +- if (!rdp_print_brush_capability_set(s, length)) ++ if (!rdp_print_brush_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_GLYPH_CACHE: +- if (!rdp_print_glyph_cache_capability_set(s, length)) ++ if (!rdp_print_glyph_cache_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_OFFSCREEN_CACHE: +- if (!rdp_print_offscreen_bitmap_cache_capability_set(s, length)) ++ if (!rdp_print_offscreen_bitmap_cache_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT: +- if (!rdp_print_bitmap_cache_host_support_capability_set(s, length)) ++ if (!rdp_print_bitmap_cache_host_support_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CACHE_V2: +- if (!rdp_print_bitmap_cache_v2_capability_set(s, length)) ++ if (!rdp_print_bitmap_cache_v2_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_VIRTUAL_CHANNEL: +- if (!rdp_print_virtual_channel_capability_set(s, length)) ++ if (!rdp_print_virtual_channel_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_DRAW_NINE_GRID_CACHE: +- if (!rdp_print_draw_nine_grid_cache_capability_set(s, length)) ++ if (!rdp_print_draw_nine_grid_cache_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_DRAW_GDI_PLUS: +- if (!rdp_print_draw_gdiplus_cache_capability_set(s, length)) ++ if (!rdp_print_draw_gdiplus_cache_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_RAIL: +- if (!rdp_print_remote_programs_capability_set(s, length)) ++ if (!rdp_print_remote_programs_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_WINDOW: +- if (!rdp_print_window_list_capability_set(s, length)) ++ if (!rdp_print_window_list_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_COMP_DESK: +- if (!rdp_print_desktop_composition_capability_set(s, length)) ++ if (!rdp_print_desktop_composition_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE: +- if (!rdp_print_multifragment_update_capability_set(s, length)) ++ if (!rdp_print_multifragment_update_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_LARGE_POINTER: +- if (!rdp_print_large_pointer_capability_set(s, length)) ++ if (!rdp_print_large_pointer_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_SURFACE_COMMANDS: +- if (!rdp_print_surface_commands_capability_set(s, length)) ++ if (!rdp_print_surface_commands_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CODECS: +- if (!rdp_print_bitmap_codecs_capability_set(s, length)) ++ if (!rdp_print_bitmap_codecs_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_FRAME_ACKNOWLEDGE: +- if (!rdp_print_frame_acknowledge_capability_set(s, length)) ++ if (!rdp_print_frame_acknowledge_capability_set(&sub)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID: +- if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(s, length)) ++ if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(&sub)) + return FALSE; + + break; +@@ -3505,13 +3485,13 @@ static BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, + break; + } + +- if (Stream_Pointer(s) != em) ++ rest = Stream_GetRemainingLength(&sub); ++ if (rest > 0) + { + WLog_ERR(TAG, "incorrect offset, type:0x%04"PRIX16" actual:%"PRIuz" expected:%"PRIuz"", +- type, Stream_Pointer(s) - bm, em - bm); ++ type, length + rest, length); + } + +- Stream_SetPointer(s, em); + numberCapabilities--; + } + +@@ -3520,21 +3500,25 @@ static BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, + #endif + + static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, +- UINT16 numberCapabilities) ++ UINT16 numberCapabilities, UINT16 totalLength) + { +- BYTE* mark; +- UINT16 count; +- UINT16 type; +- UINT16 length; +- BYTE* bm, *em; + BOOL treated; +- Stream_GetPointer(s, mark); +- count = numberCapabilities; +- ++ size_t start, end, len; ++ UINT16 count = numberCapabilities; ++ ++ start = Stream_GetPosition(s); + while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4) + { +- Stream_GetPointer(s, bm); +- rdp_read_capability_set_header(s, &length, &type); ++ size_t rest; ++ UINT16 type; ++ UINT16 length; ++ wStream sub; ++ ++ if (!rdp_read_capability_set_header(s, &length, &type)) ++ return FALSE; ++ Stream_StaticInit(&sub, Stream_Pointer(s), length - 4); ++ if (!Stream_SafeSeek(s, length - 4)) ++ return FALSE; + + if (type < 32) + { +@@ -3545,128 +3529,120 @@ static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, + WLog_WARN(TAG, "not handling capability type %"PRIu16" yet", type); + } + +- em = bm + length; +- +- if (Stream_GetRemainingLength(s) < ((size_t) length - 4)) +- { +- WLog_ERR(TAG, "error processing stream"); +- return FALSE; +- } +- + treated = TRUE; + + switch (type) + { + case CAPSET_TYPE_GENERAL: +- if (!rdp_read_general_capability_set(s, length, settings)) ++ if (!rdp_read_general_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP: +- if (!rdp_read_bitmap_capability_set(s, length, settings)) ++ if (!rdp_read_bitmap_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_ORDER: +- if (!rdp_read_order_capability_set(s, length, settings)) ++ if (!rdp_read_order_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_POINTER: +- if (!rdp_read_pointer_capability_set(s, length, settings)) ++ if (!rdp_read_pointer_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_INPUT: +- if (!rdp_read_input_capability_set(s, length, settings)) ++ if (!rdp_read_input_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_VIRTUAL_CHANNEL: +- if (!rdp_read_virtual_channel_capability_set(s, length, settings)) ++ if (!rdp_read_virtual_channel_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_SHARE: +- if (!rdp_read_share_capability_set(s, length, settings)) ++ if (!rdp_read_share_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_COLOR_CACHE: +- if (!rdp_read_color_cache_capability_set(s, length, settings)) ++ if (!rdp_read_color_cache_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_FONT: +- if (!rdp_read_font_capability_set(s, length, settings)) ++ if (!rdp_read_font_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_DRAW_GDI_PLUS: +- if (!rdp_read_draw_gdiplus_cache_capability_set(s, length, settings)) ++ if (!rdp_read_draw_gdiplus_cache_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_RAIL: +- if (!rdp_read_remote_programs_capability_set(s, length, settings)) ++ if (!rdp_read_remote_programs_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_WINDOW: +- if (!rdp_read_window_list_capability_set(s, length, settings)) ++ if (!rdp_read_window_list_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE: +- if (!rdp_read_multifragment_update_capability_set(s, length, settings)) ++ if (!rdp_read_multifragment_update_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_LARGE_POINTER: +- if (!rdp_read_large_pointer_capability_set(s, length, settings)) ++ if (!rdp_read_large_pointer_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_COMP_DESK: +- if (!rdp_read_desktop_composition_capability_set(s, length, settings)) ++ if (!rdp_read_desktop_composition_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_SURFACE_COMMANDS: +- if (!rdp_read_surface_commands_capability_set(s, length, settings)) ++ if (!rdp_read_surface_commands_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CODECS: +- if (!rdp_read_bitmap_codecs_capability_set(s, length, settings)) ++ if (!rdp_read_bitmap_codecs_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_FRAME_ACKNOWLEDGE: +- if (!rdp_read_frame_acknowledge_capability_set(s, length, settings)) ++ if (!rdp_read_frame_acknowledge_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID: +- if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(s, length, settings)) ++ if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(&sub, settings)) + return FALSE; + + break; +@@ -3684,55 +3660,55 @@ static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, + switch (type) + { + case CAPSET_TYPE_BITMAP_CACHE: +- if (!rdp_read_bitmap_cache_capability_set(s, length, settings)) ++ if (!rdp_read_bitmap_cache_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_BITMAP_CACHE_V2: +- if (!rdp_read_bitmap_cache_v2_capability_set(s, length, settings)) ++ if (!rdp_read_bitmap_cache_v2_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_BRUSH: +- if (!rdp_read_brush_capability_set(s, length, settings)) ++ if (!rdp_read_brush_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_GLYPH_CACHE: +- if (!rdp_read_glyph_cache_capability_set(s, length, settings)) ++ if (!rdp_read_glyph_cache_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_OFFSCREEN_CACHE: +- if (!rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings)) ++ if (!rdp_read_offscreen_bitmap_cache_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_SOUND: +- if (!rdp_read_sound_capability_set(s, length, settings)) ++ if (!rdp_read_sound_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_CONTROL: +- if (!rdp_read_control_capability_set(s, length, settings)) ++ if (!rdp_read_control_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_ACTIVATION: +- if (!rdp_read_window_activation_capability_set(s, length, settings)) ++ if (!rdp_read_window_activation_capability_set(&sub, settings)) + return FALSE; + + break; + + case CAPSET_TYPE_DRAW_NINE_GRID_CACHE: +- if (!rdp_read_draw_nine_grid_cache_capability_set(s, length, settings)) ++ if (!rdp_read_draw_nine_grid_cache_capability_set(&sub, settings)) + return FALSE; + + break; +@@ -3749,7 +3725,7 @@ static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, + switch (type) + { + case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT: +- if (!rdp_read_bitmap_cache_host_support_capability_set(s, length, settings)) ++ if (!rdp_read_bitmap_cache_host_support_capability_set(&sub, settings)) + return FALSE; + + break; +@@ -3762,16 +3738,19 @@ static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, + } + } + +- if (Stream_Pointer(s) != em) ++ rest = Stream_GetRemainingLength(&sub); ++ if (rest > 0) + { + WLog_ERR(TAG, "incorrect offset, type:0x%04"PRIX16" actual:%"PRIuz" expected:%"PRIuz"", +- type, Stream_Pointer(s) - bm, em - bm); ++ type, length - rest, length); + } + +- Stream_SetPointer(s, em); + numberCapabilities--; + } + ++ end = Stream_GetPosition(s); ++ len = end - start; ++ + if (numberCapabilities) + { + WLog_ERR(TAG, +@@ -3780,19 +3759,25 @@ static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, + } + + #ifdef WITH_DEBUG_CAPABILITIES +- Stream_GetPointer(s, em); +- Stream_SetPointer(s, mark); +- numberCapabilities = count; +- rdp_print_capability_sets(s, numberCapabilities, TRUE); +- Stream_SetPointer(s, em); ++ { ++ Stream_SetPosition(s, start); ++ numberCapabilities = count; ++ rdp_print_capability_sets(s, numberCapabilities, TRUE); ++ Stream_SetPosition(s, end); ++ } + #endif ++ if (len > totalLength) ++ { ++ WLog_ERR(TAG, "Capability length expected %" PRIu16 ", actual %" PRIdz, totalLength, len); ++ return FALSE; ++ } + return TRUE; + } + + BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId) + { +- UINT16 length; + UINT16 securityFlags = 0; ++ UINT16 length; + + if (!rdp_read_header(rdp, s, &length, pChannelId)) + return FALSE; +@@ -3889,7 +3874,7 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ + + /* capabilitySets */ +- if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities)) ++ if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities, lengthCombinedCapabilities)) + { + WLog_ERR(TAG, "rdp_read_capability_sets failed"); + return FALSE; +@@ -4008,7 +3993,8 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s) + Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor */ + Stream_Read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ +- status = rdp_read_capability_sets(s, rdp->settings, numberCapabilities); ++ if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities, lengthCombinedCapabilities)) ++ return FALSE; + + if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS]) + { + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,61 @@ +--- a/libfreerdp/cache/bitmap.c ++++ b/libfreerdp/cache/bitmap.c +@@ -236,7 +236,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, + { + rdpBitmap* bitmap; + +- if (id > bitmapCache->maxCells) ++ if (id >= bitmapCache->maxCells) + { + WLog_ERR(TAG, "get invalid bitmap cell id: %"PRIu32"", id); + return NULL; +@@ -294,7 +294,7 @@ void bitmap_cache_register_callbacks(rdpUpdate* update) + + rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) + { +- int i; ++ UINT32 i; + rdpBitmapCache* bitmapCache; + bitmapCache = (rdpBitmapCache*) calloc(1, sizeof(rdpBitmapCache)); + +@@ -311,7 +311,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) + if (!bitmapCache->cells) + goto fail; + +- for (i = 0; i < (int) bitmapCache->maxCells; i++) ++ for (i = 0; i < bitmapCache->maxCells; i++) + { + bitmapCache->cells[i].number = settings->BitmapCacheV2CellInfo[i].numEntries; + /* allocate an extra entry for BITMAP_CACHE_WAITING_LIST_INDEX */ +@@ -325,26 +325,20 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) + return bitmapCache; + fail: + +- if (bitmapCache->cells) +- { +- for (i = 0; i < (int) bitmapCache->maxCells; i++) +- free(bitmapCache->cells[i].entries); +- } +- +- free(bitmapCache); ++ bitmap_cache_free(bitmapCache); + return NULL; + } + + void bitmap_cache_free(rdpBitmapCache* bitmapCache) + { +- int i, j; ++ UINT32 i, j; + rdpBitmap* bitmap; + + if (bitmapCache) + { +- for (i = 0; i < (int) bitmapCache->maxCells; i++) ++ for (i = 0; i < bitmapCache->maxCells; i++) + { +- for (j = 0; j < (int) bitmapCache->cells[i].number + 1; j++) ++ for (j = 0; j < bitmapCache->cells[i].number + 1; j++) + { + bitmap = bitmapCache->cells[i].entries[j]; + Bitmap_Free(bitmapCache->context, bitmap); + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,19 @@ +--- a/libfreerdp/core/orders.c ++++ b/libfreerdp/core/orders.c +@@ -3612,7 +3612,14 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, + Stream_Read_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Read_UINT8(s, orderType); /* orderType (1 byte) */ +- next = Stream_Pointer(s) + ((INT16) orderLength) + 7; ++ if (Stream_GetRemainingLength(s) < orderLength + 7) ++ { ++ WLog_Print(update->log, WLOG_ERROR, "Stream_GetRemainingLength(s) %" PRIuz " < %" PRIu16, ++ Stream_GetRemainingLength(s), orderLength + 7); ++ return FALSE; ++ } ++ ++ next = Stream_Pointer(s) + orderLength + 7; + name = secondary_order_string(orderType); + WLog_Print(update->log, WLOG_DEBUG, "Secondary Drawing Order %s", name); + + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,214 @@ +--- a/libfreerdp/gdi/region.c ++++ b/libfreerdp/gdi/region.c +@@ -37,6 +37,27 @@ + + #define TAG FREERDP_TAG("gdi.region") + ++static char* gdi_rect_str(char* buffer, size_t size, const HGDI_RECT rect) ++{ ++ _snprintf(buffer, size - 1, ++ "[top/left=%" PRId32 "x%" PRId32 "-bottom/right%" PRId32 "x%" PRId32 "]", rect->top, ++ rect->left, rect->bottom, rect->right); ++ if (size > 1) ++ buffer[size - 1] = '\0'; ++ ++ return buffer; ++} ++ ++static char* gdi_regn_str(char* buffer, size_t size, const HGDI_RGN rgn) ++{ ++ _snprintf(buffer, size - 1, "[%" PRId32 "x%" PRId32 "-%" PRId32 "x%" PRId32 "]", rgn->x, rgn->y, ++ rgn->w, rgn->h); ++ if (size > 1) ++ buffer[size - 1] = '\0'; ++ ++ return buffer; ++} ++ + /** + * Create a region from rectangular coordinates.\n + * @msdn{dd183514} +@@ -50,7 +71,20 @@ + HGDI_RGN gdi_CreateRectRgn(INT32 nLeftRect, INT32 nTopRect, + INT32 nRightRect, INT32 nBottomRect) + { +- HGDI_RGN hRgn = (HGDI_RGN) calloc(1, sizeof(GDI_RGN)); ++ INT64 w, h; ++ HGDI_RGN hRgn; ++ ++ w = nRightRect - nLeftRect + 1ll; ++ h = nBottomRect - nTopRect + 1ll; ++ if ((w < 0) || (h < 0) || (w > INT32_MAX) || (h > INT32_MAX)) ++ { ++ WLog_ERR(TAG, ++ "Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32 ++ "x%" PRId32, ++ nTopRect, nLeftRect, nBottomRect, nRightRect); ++ return NULL; ++ } ++ hRgn = (HGDI_RGN)calloc(1, sizeof(GDI_RGN)); + + if (!hRgn) + return NULL; +@@ -58,8 +92,8 @@ HGDI_RGN gdi_CreateRectRgn(INT32 nLeftRect, INT32 nTopRect, + hRgn->objectType = GDIOBJECT_REGION; + hRgn->x = nLeftRect; + hRgn->y = nTopRect; +- hRgn->w = nRightRect - nLeftRect + 1; +- hRgn->h = nBottomRect - nTopRect + 1; ++ hRgn->w = w; ++ hRgn->h = h; + hRgn->null = FALSE; + return hRgn; + } +@@ -97,10 +131,24 @@ HGDI_RECT gdi_CreateRect(INT32 xLeft, INT32 yTop, + + INLINE void gdi_RectToRgn(HGDI_RECT rect, HGDI_RGN rgn) + { ++ INT64 w, h; ++ w = rect->right - rect->left + 1ll; ++ h = rect->bottom - rect->top + 1ll; ++ ++ if ((w < 0) || (h < 0) || (w > INT32_MAX) || (h > INT32_MAX)) ++ { ++ WLog_ERR(TAG, ++ "Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32 ++ "x%" PRId32, ++ rect->top, rect->left, rect->bottom, rect->right); ++ w = 0; ++ h = 0; ++ } ++ + rgn->x = rect->left; + rgn->y = rect->top; +- rgn->w = rect->right - rect->left + 1; +- rgn->h = rect->bottom - rect->top + 1; ++ rgn->w = w; ++ rgn->h = h; + } + + /** +@@ -115,10 +163,24 @@ INLINE void gdi_RectToRgn(HGDI_RECT rect, HGDI_RGN rgn) + INLINE void gdi_CRectToRgn(INT32 left, INT32 top, + INT32 right, INT32 bottom, HGDI_RGN rgn) + { ++ INT64 w, h; ++ w = right - left + 1ll; ++ h = bottom - top + 1ll; ++ ++ if ((w < 0) || (h < 0) || (w > INT32_MAX) || (h > INT32_MAX)) ++ { ++ WLog_ERR(TAG, ++ "Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32 ++ "x%" PRId32, ++ top, left, bottom, right); ++ w = 0; ++ h = 0; ++ } ++ + rgn->x = left; + rgn->y = top; +- rgn->w = right - left + 1; +- rgn->h = bottom - top + 1; ++ rgn->w = w; ++ rgn->h = h; + } + + /** +@@ -134,10 +196,29 @@ INLINE void gdi_RectToCRgn(const HGDI_RECT rect, + INT32* x, INT32* y, + INT32* w, INT32* h) + { ++ INT64 tmp; + *x = rect->left; + *y = rect->top; +- *w = rect->right - rect->left + 1; +- *h = rect->bottom - rect->top + 1; ++ tmp = rect->right - rect->left + 1; ++ if ((tmp < 0) || (tmp > INT32_MAX)) ++ { ++ char buffer[256]; ++ WLog_ERR(TAG, "[%s] rectangle invalid %s", __FUNCTION__, ++ gdi_rect_str(buffer, sizeof(buffer), rect)); ++ *w = 0; ++ } ++ else ++ *w = tmp; ++ tmp = rect->bottom - rect->top + 1; ++ if ((tmp < 0) || (tmp > INT32_MAX)) ++ { ++ char buffer[256]; ++ WLog_ERR(TAG, "[%s] rectangle invalid %s", __FUNCTION__, ++ gdi_rect_str(buffer, sizeof(buffer), rect)); ++ *h = 0; ++ } ++ else ++ *h = tmp; + } + + /** +@@ -156,10 +237,24 @@ INLINE void gdi_CRectToCRgn(INT32 left, INT32 top, INT32 right, + INT32 bottom, + INT32* x, INT32* y, INT32* w, INT32* h) + { ++ INT64 wl, hl; ++ wl = right - left + 1ll; ++ hl = bottom - top + 1ll; ++ ++ if ((wl < 0) || (hl < 0) || (wl > INT32_MAX) || (hl > INT32_MAX)) ++ { ++ WLog_ERR(TAG, ++ "Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32 ++ "x%" PRId32, ++ top, left, bottom, right); ++ w = 0; ++ h = 0; ++ } ++ + *x = left; + *y = top; +- *w = right - left + 1; +- *h = bottom - top + 1; ++ *w = wl; ++ *h = hl; + } + + /** +@@ -170,10 +265,21 @@ INLINE void gdi_CRectToCRgn(INT32 left, INT32 top, INT32 right, + + INLINE void gdi_RgnToRect(HGDI_RGN rgn, HGDI_RECT rect) + { ++ INT64 r, b; ++ r = rgn->x + rgn->w - 1ll; ++ b = rgn->y + rgn->h - 1ll; ++ ++ if ((r < INT32_MIN) || (r > INT32_MAX) || (b < INT32_MIN) || (b > INT32_MAX)) ++ { ++ char buffer[256]; ++ WLog_ERR(TAG, "Can not create region %s", gdi_regn_str(buffer, sizeof(buffer), rgn)); ++ r = rgn->x; ++ b = rgn->y; ++ } + rect->left = rgn->x; + rect->top = rgn->y; +- rect->right = rgn->x + rgn->w - 1; +- rect->bottom = rgn->y + rgn->h - 1; ++ rect->right = r; ++ rect->bottom = b; + } + + /** +@@ -225,6 +331,12 @@ INLINE void gdi_CRgnToRect(INT64 x, INT64 y, INT32 w, INT32 h, + INLINE void gdi_RgnToCRect(HGDI_RGN rgn, INT32* left, INT32* top, + INT32* right, INT32* bottom) + { ++ if ((rgn->w < 0) || (rgn->h < 0)) ++ { ++ char buffer[256]; ++ WLog_ERR(TAG, "Can not create region %s", gdi_regn_str(buffer, sizeof(buffer), rgn)); ++ } ++ + *left = rgn->x; + *top = rgn->y; + *right = rgn->x + rgn->w - 1; + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,26 @@ +--- a/libfreerdp/codec/include/bitmap.c ++++ b/libfreerdp/codec/include/bitmap.c +@@ -338,6 +338,9 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, + case MEGA_MEGA_COLOR_IMAGE: + runLength = ExtractRunLength(code, pbSrc, &advance); + pbSrc = pbSrc + advance; ++ if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength)) ++ return FALSE; ++ + UNROLL(runLength, + { + SRCREADPIXEL(temp, pbSrc); +diff --git a/libfreerdp/codec/interleaved.c b/libfreerdp/codec/interleaved.c +index a3fe7dd..0d36e9b 100644 +--- a/libfreerdp/codec/interleaved.c ++++ b/libfreerdp/codec/interleaved.c +@@ -215,7 +215,7 @@ static INLINE BOOL ensure_capacity(const BYTE* start, const BYTE* end, size_t si + { + const size_t available = (uintptr_t)end - (uintptr_t)start; + const BOOL rc = available >= size * base; +- return rc; ++ return rc && (start <= end); + } + + static INLINE void write_pixel_8(BYTE* _buf, BYTE _pix) + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,70 @@ +--- a/libfreerdp/core/orders.c ++++ b/libfreerdp/core/orders.c +@@ -888,15 +888,19 @@ static INLINE BOOL update_write_brush(wStream* s, rdpBrush* brush, + return TRUE; + } + static INLINE BOOL update_read_delta_rects(wStream* s, DELTA_RECT* rectangles, +- UINT32 number) ++ UINT32 *nr) + { ++ UINT32 number = *nr; + UINT32 i; + BYTE flags = 0; + BYTE* zeroBits; + UINT32 zeroBitsSize; + + if (number > 45) +- number = 45; ++ { ++ WLog_WARN(TAG, "Invalid number of delta rectangles %" PRIu32, number); ++ return FALSE; ++ } + + zeroBitsSize = ((number + 1) / 2); + +@@ -1293,7 +1297,7 @@ static BOOL update_read_multi_dstblt_order(wStream* s, const ORDER_INFO* orderIn + + Stream_Read_UINT16(s, multi_dstblt->cbData); + return update_read_delta_rects(s, multi_dstblt->rectangles, +- multi_dstblt->numRectangles); ++ &multi_dstblt->numRectangles); + } + + return TRUE; +@@ -1322,7 +1326,7 @@ static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderIn + Stream_Read_UINT16(s, multi_patblt->cbData); + + if (!update_read_delta_rects(s, multi_patblt->rectangles, +- multi_patblt->numRectangles)) ++ &multi_patblt->numRectangles)) + return FALSE; + } + +@@ -1347,7 +1351,7 @@ static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderIn + + Stream_Read_UINT16(s, multi_scrblt->cbData); + return update_read_delta_rects(s, multi_scrblt->rectangles, +- multi_scrblt->numRectangles); ++ &multi_scrblt->numRectangles); + } + + return TRUE; +@@ -1401,7 +1405,7 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, + + Stream_Read_UINT16(s, multi_opaque_rect->cbData); + return update_read_delta_rects(s, multi_opaque_rect->rectangles, +- multi_opaque_rect->numRectangles); ++ &multi_opaque_rect->numRectangles); + } + + return TRUE; +@@ -1424,7 +1428,7 @@ static BOOL update_read_multi_draw_nine_grid_order(wStream* s, + + Stream_Read_UINT16(s, multi_draw_nine_grid->cbData); + return update_read_delta_rects(s, multi_draw_nine_grid->rectangles, +- multi_draw_nine_grid->nDeltaEntries); ++ &multi_draw_nine_grid->nDeltaEntries); + } + + return TRUE; + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,77 @@ +--- a/libfreerdp/codec/planar.c ++++ b/libfreerdp/codec/planar.c +@@ -42,10 +42,9 @@ static INLINE BYTE* freerdp_bitmap_planar_delta_encode_plane( + static INLINE INT32 planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, + UINT32 nWidth, UINT32 nHeight) + { ++ UINT32 used = 0; + UINT32 x, y; + BYTE controlByte; +- const BYTE* pRLE = pSrcData; +- const BYTE* pEnd = &pSrcData[SrcSize]; + + for (y = 0; y < nHeight; y++) + { +@@ -54,10 +53,10 @@ static INLINE INT32 planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, + int cRawBytes; + int nRunLength; + +- if (pRLE >= pEnd) ++ if (used >= SrcSize) + return -1; + +- controlByte = *pRLE++; ++ controlByte = pSrcData[used++]; + nRunLength = PLANAR_CONTROL_BYTE_RUN_LENGTH(controlByte); + cRawBytes = PLANAR_CONTROL_BYTE_RAW_BYTES(controlByte); + +@@ -72,19 +71,21 @@ static INLINE INT32 planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, + cRawBytes = 0; + } + +- pRLE += cRawBytes; ++ used += cRawBytes; + x += cRawBytes; + x += nRunLength; + + if (x > nWidth) + return -1; + +- if (pRLE > pEnd) ++ if (used > SrcSize) + return -1; + } + } + +- return (INT32)(pRLE - pSrcData); ++ if (used > INT32_MAX) ++ return -1; ++ return (INT32)used; + } + + static INLINE INT32 planar_decompress_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, +diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c +index d004289..d4707ba 100644 +--- a/libfreerdp/core/orders.c ++++ b/libfreerdp/core/orders.c +@@ -1965,6 +1965,9 @@ static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wSt + } + } + ++ if (cache_bitmap->bitmapLength == 0) ++ goto fail; ++ + if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength) + goto fail; + +@@ -2099,6 +2102,9 @@ static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* updat + } + } + ++ if (cache_bitmap_v2->bitmapLength == 0) ++ goto fail; ++ + if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength) + goto fail; + + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0019-Fixed-possible-NULL-access.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0019-Fixed-possible-NULL-access.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0019-Fixed-possible-NULL-access.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0019-Fixed-possible-NULL-access.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,45 @@ +--- a/libfreerdp/cache/bitmap.c ++++ b/libfreerdp/cache/bitmap.c +@@ -314,12 +314,13 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) + for (i = 0; i < bitmapCache->maxCells; i++) + { + bitmapCache->cells[i].number = settings->BitmapCacheV2CellInfo[i].numEntries; ++ BITMAP_V2_CELL* cell = &bitmapCache->cells[i]; ++ UINT32 nr = settings->BitmapCacheV2CellInfo[i].numEntries; + /* allocate an extra entry for BITMAP_CACHE_WAITING_LIST_INDEX */ +- bitmapCache->cells[i].entries = (rdpBitmap**) calloc(( +- bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*)); +- +- if (!bitmapCache->cells[i].entries) ++ cell->entries = (rdpBitmap**)calloc((nr + 1), sizeof(rdpBitmap*)); ++ if (!cell->entries) + goto fail; ++ cell->number = nr; + } + + return bitmapCache; +@@ -331,16 +332,18 @@ fail: + + void bitmap_cache_free(rdpBitmapCache* bitmapCache) + { +- UINT32 i, j; +- rdpBitmap* bitmap; +- + if (bitmapCache) + { ++ UINT32 i; + for (i = 0; i < bitmapCache->maxCells; i++) + { +- for (j = 0; j < bitmapCache->cells[i].number + 1; j++) ++ UINT32 j; ++ BITMAP_V2_CELL* cell = &bitmapCache->cells[i]; ++ if (!cell->entries) ++ continue; ++ for (j = 0; j < cell->number + 1; j++) + { +- bitmap = bitmapCache->cells[i].entries[j]; ++ rdpBitmap* bitmap = cell->entries[j]; + Bitmap_Free(bitmapCache->context, bitmap); + } + + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch 1970-01-01 01:00:00.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch 2020-06-01 13:01:09.000000000 +0200 @@ -0,0 +1,16 @@ +--- a/libfreerdp/gdi/region.c ++++ b/libfreerdp/gdi/region.c +@@ -553,9 +553,11 @@ INLINE BOOL gdi_InvalidateRegion(HGDI_DC hdc, INT32 x, INT32 y, INT32 w, + + if ((hdc->hwnd->ninvalid + 1) > hdc->hwnd->count) + { +- int new_cnt; ++ size_t new_cnt; + HGDI_RGN new_rgn; + new_cnt = hdc->hwnd->count * 2; ++ if (new_cnt > UINT32_MAX) ++ return FALSE; + new_rgn = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * new_cnt); + + if (!new_rgn) + diff -Nru freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/series freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/series --- freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/series 2019-12-16 11:35:50.000000000 +0100 +++ freerdp2-2.0.0~git20190204.1.2693389a+dfsg1/debian/patches/series 2020-06-01 13:05:44.000000000 +0200 @@ -1,2 +1,21 @@ 1001_spelling-fixes.patch 0001_CVE-2019-17177.patch +0002_fix-channels-smartcard-fix-statusw-call.patch +0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch +0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch +0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch +0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch +0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch +0008-Fixed-6013-Check-new-length-is-0.patch +0009-Fix-6010-Check-length-in-read_icon_info.patch +0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch +0011-Fixed-Stream_-macros-bracing-arguments.patch +0012-Use-safe-seek-for-capability-parsing.patch +0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch +0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch +0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch +0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch +0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch +0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch +0019-Fixed-possible-NULL-access.patch +0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch