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

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



Your message dated Sat, 01 Aug 2020 12:51:28 +0100
with message-id <43535efb498a168cf81452ca0c326f004f46adc6.camel@adam-barratt.org.uk>
and subject line Closing bugs for fixes included in 10.5 point release
has caused the Debian Bug report #961978,
regarding buster-pu: package freerdp2/2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
961978: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=961978
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
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

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 10.5

Hi,

Each of these bugs relates to an update that was included in today's
stable point release.

Regards,

Adam

--- End Message ---

Reply to: