[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#961978: buster-pu: package freerdp2/2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u2



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@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 <sunweaver@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.miklautz@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

Reply to: