debian/patches: add security related patches from upstream
Back ported patches of multiple security issues were added. Including the following CVEs: * CVE-2020-11521 * CVE-2020-11522 * CVE-2020-11523 * CVE-2020-11524 * CVE-2020-11525 * CVE-2020-11526
This commit is contained in:
parent
85341458bc
commit
163efd4c7d
30
debian/changelog
vendored
30
debian/changelog
vendored
@ -1,3 +1,33 @@
|
||||
freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u2) buster-security; urgency=medium
|
||||
|
||||
* 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
|
||||
|
||||
-- Bernhard Miklautz <bernhard.miklautz@shacknet.at> Mon, 13 Apr 2020 21:31:35 +0000
|
||||
|
||||
freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u1) buster; urgency=medium
|
||||
|
||||
* debian/patches:
|
||||
|
||||
81
debian/patches/0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch
vendored
Normal file
81
debian/patches/0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch
vendored
Normal file
@ -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);
|
||||
11
debian/patches/0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch
vendored
Normal file
11
debian/patches/0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch
vendored
Normal file
@ -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) */
|
||||
|
||||
28
debian/patches/0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch
vendored
Normal file
28
debian/patches/0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch
vendored
Normal file
@ -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;
|
||||
|
||||
12
debian/patches/0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch
vendored
Normal file
12
debian/patches/0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch
vendored
Normal file
@ -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,
|
||||
16
debian/patches/0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch
vendored
Normal file
16
debian/patches/0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch
vendored
Normal file
@ -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;
|
||||
|
||||
11
debian/patches/0008-Fixed-6013-Check-new-length-is-0.patch
vendored
Normal file
11
debian/patches/0008-Fixed-6013-Check-new-length-is-0.patch
vendored
Normal file
@ -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);
|
||||
43
debian/patches/0009-Fix-6010-Check-length-in-read_icon_info.patch
vendored
Normal file
43
debian/patches/0009-Fix-6010-Check-length-in-read_icon_info.patch
vendored
Normal file
@ -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;
|
||||
}
|
||||
|
||||
94
debian/patches/0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch
vendored
Normal file
94
debian/patches/0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch
vendored
Normal file
@ -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;
|
||||
|
||||
109
debian/patches/0011-Fixed-Stream_-macros-bracing-arguments.patch
vendored
Normal file
109
debian/patches/0011-Fixed-Stream_-macros-bracing-arguments.patch
vendored
Normal file
@ -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)
|
||||
|
||||
1835
debian/patches/0012-Use-safe-seek-for-capability-parsing.patch
vendored
Normal file
1835
debian/patches/0012-Use-safe-seek-for-capability-parsing.patch
vendored
Normal file
File diff suppressed because it is too large
Load Diff
61
debian/patches/0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch
vendored
Normal file
61
debian/patches/0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch
vendored
Normal file
@ -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);
|
||||
|
||||
19
debian/patches/0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch
vendored
Normal file
19
debian/patches/0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch
vendored
Normal file
@ -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);
|
||||
|
||||
|
||||
214
debian/patches/0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch
vendored
Normal file
214
debian/patches/0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch
vendored
Normal file
@ -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;
|
||||
|
||||
26
debian/patches/0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch
vendored
Normal file
26
debian/patches/0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch
vendored
Normal file
@ -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)
|
||||
|
||||
70
debian/patches/0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch
vendored
Normal file
70
debian/patches/0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch
vendored
Normal file
@ -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;
|
||||
|
||||
77
debian/patches/0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch
vendored
Normal file
77
debian/patches/0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch
vendored
Normal file
@ -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;
|
||||
|
||||
|
||||
45
debian/patches/0019-Fixed-possible-NULL-access.patch
vendored
Normal file
45
debian/patches/0019-Fixed-possible-NULL-access.patch
vendored
Normal file
@ -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);
|
||||
}
|
||||
|
||||
|
||||
16
debian/patches/0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch
vendored
Normal file
16
debian/patches/0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch
vendored
Normal file
@ -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)
|
||||
|
||||
19
debian/patches/series
vendored
19
debian/patches/series
vendored
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user