Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian....@packages.debian.org
Usertags: pu

Dear release team,

I just uploaded this update of freerdp2 to Debian buster. Thanks to
Bernhard Miklautz, we have several security patches available:

+  [ Bernhard Miklautz ]
+  * debian/patches - security releated backports from upstream
+    * Add 0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch
+    * Add 0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch
+    * Add 0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch
+    * Add 0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch
+    * Add 0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch
+    * Add 0008-Fixed-6013-Check-new-length-is-0.patch
+    * Add 0009-Fix-6010-Check-length-in-read_icon_info.patch
+    * Add 0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch
+    * Add 0011-Fixed-Stream_-macros-bracing-arguments.patch
+    * Add 0012-Use-safe-seek-for-capability-parsing.patch
+    * Add 0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch
+      (CVE-2020-11525).
+    * Add 0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch
+      (CVE-2020-11526).
+    * Add 0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch
+      (CVE-2020-11523).
+    * Add 0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch
+      (CVE-2020-11524).
+    * Add 0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch
+      (CVE-2020-11522).
+    * Add 0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch
+      (CVE-2020-11521).
+    * Add 0019-Fixed-possible-NULL-access.patch
+    * Add 0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch

-> This patchwork will be the first round of CVE closures (all no-dsa, as
discussed with Salvatore from the security team). Whenever Bernhard finds
time, he will provide more patches and a +deb10u3 is probably already in
sight.

+  [ Mike Gabriel ]
+  * debian/patches:
+    + Add 0002_fix-channels-smartcard-fix-statusw-call.patch. Fix smartcard
+      login failures. (Closes: #919281).

-> a functionality fix for people using smartcard readers with FreeRDP.

Thanks+Greets,
Mike


-- System Information:
Debian Release: 10.4
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'proposed-updates'), (500, 
'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

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

Reply via email to