Compare commits
49 Commits
master
...
debian/bus
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a62ef46b9b | ||
|
|
528ad1ee7f | ||
|
|
9c2cb890eb | ||
|
|
1cddd4643a | ||
|
|
ad925990b3 | ||
|
|
cb0fee7d81 | ||
|
|
343a6e9965 | ||
|
|
180fc8f332 | ||
|
|
326341043d | ||
|
|
b7fad42bde | ||
|
|
eb2c3e598e | ||
|
|
ae332a9e65 | ||
|
|
9abf5f033b | ||
|
|
56d1291988 | ||
|
|
3f665697f0 | ||
|
|
a8d9578fb9 | ||
|
|
14442af9ac | ||
|
|
8f234906e9 | ||
|
|
6ebfab5ec1 | ||
|
|
bb305bcdf7 | ||
|
|
f1641af0fd | ||
|
|
b743b819c0 | ||
|
|
d9179e0766 | ||
|
|
24c51f4ed8 | ||
|
|
f6f2bf7896 | ||
|
|
0f3fd7d339 | ||
|
|
d1217c6dad | ||
|
|
09055cabae | ||
|
|
ab18013d96 | ||
|
|
2dacc519e5 | ||
|
|
792f6a14d1 | ||
|
|
a4c483bc30 | ||
|
|
43cbb16760 | ||
|
|
500b4499a7 | ||
|
|
6ae95183f4 | ||
|
|
21305b53c4 | ||
|
|
efc916e1a4 | ||
|
|
b6e609f697 | ||
|
|
0333c99067 | ||
|
|
6e4db706a5 | ||
|
|
0359d79a4b | ||
|
|
6dd3e7854d | ||
|
|
03201de47f | ||
|
|
4db4aa6d33 | ||
|
|
0553695929 | ||
|
|
bdab8340a1 | ||
|
|
163efd4c7d | ||
|
|
85341458bc | ||
|
|
c6fe442da0 |
10
debian/.gitlab-ci.yml
vendored
Normal file
10
debian/.gitlab-ci.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
include:
|
||||
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
|
||||
|
||||
variables:
|
||||
RELEASE: 'buster'
|
||||
SALSA_CI_COMPONENTS: 'main contrib non-free'
|
||||
SALSA_CI_DISABLE_REPROTEST: 1
|
||||
SALSA_CI_DISABLE_LINTIAN: 1
|
||||
SALSA_CI_DISABLE_BLHC: 1
|
||||
SALSA_CI_DISABLE_PIUPARTS: 1
|
||||
106
debian/changelog
vendored
106
debian/changelog
vendored
@ -1,3 +1,65 @@
|
||||
freerdp2 (2.3.0+dfsg1-2+deb10u5) UNRELEASED; urgency=medium
|
||||
|
||||
* Fix typo in CVE number in last upload. (CVE 2022-39283 instead
|
||||
of 2023-29283)
|
||||
|
||||
-- Tobias Frost <tobi@debian.org> Fri, 17 Nov 2023 18:37:16 +0100
|
||||
|
||||
freerdp2 (2.3.0+dfsg1-2+deb10u4) buster-security; urgency=medium
|
||||
|
||||
* Non-maintainer upload by the LTS Security Team.
|
||||
* Import fix for CVE-2021-41160 - Improper region checks in all clients
|
||||
allow out of bound write to memory (Closes: #1001062)
|
||||
* Import fix for CVE-2022-24883 - FreeRDP Server authentication might allow
|
||||
invalid credentials to pass.
|
||||
* Import fix for (see #1024511)
|
||||
- CVE-2022-39316 - Out of bound read in zgfx decoder and
|
||||
- CVE-2022-39318 - Division by zero in urbdrc channel
|
||||
- CVE-2022-39319 - Missing length validation in urbdrc channel
|
||||
- CVE-2022-39347 - Missing path sanitation with `drive` channel
|
||||
- CVE-2022-41877 - Missing input length validation in `drive` channel
|
||||
* Import fix for CVE-2022-39282 and CVE-2022-39283 (Closes: #1021659)
|
||||
* Previous upload had a typo in the CVE list: It was CVE 2023-40567 not
|
||||
CVE 2023-39357; fixing changelog entry.
|
||||
|
||||
-- Tobias Frost <tobi@debian.org> Fri, 17 Nov 2023 17:29:31 +0100
|
||||
|
||||
freerdp2 (2.3.0+dfsg1-2+deb10u3) buster-security; urgency=medium
|
||||
|
||||
* Non-maintainer for the LTS security team.
|
||||
* Backport upstream version 2.3.0 from bullseye to buster.
|
||||
This adresses:
|
||||
CVE-2020-4030 CVE-2020-4031 CVE-2020-4032
|
||||
CVE-2020-4033 CVE-2020-11017 CVE-2020-11018 CVE-2020-11019
|
||||
CVE-2020-11038 CVE-2020-11039 CVE-2020-11040 CVE-2020-11041
|
||||
CVE-2020-11042 CVE-2020-11043 CVE-2020-11044 CVE-2020-11045
|
||||
CVE-2020-11046 CVE-2020-11047 CVE-2020-11048 CVE-2020-11049
|
||||
CVE-2020-11058 CVE-2020-11085 CVE-2020-11086 CVE-2020-11087
|
||||
CVE-2020-11088 CVE-2020-11089 CVE-2020-11095 CVE-2020-11096
|
||||
CVE-2020-11097 CVE-2020-11098 CVE-2020-11099 CVE-2020-13396
|
||||
CVE-2020-13397 CVE-2020-13398 and
|
||||
CVE-2020-15103 (Closes: #965979)
|
||||
* Backporting/Importing upstream patches for (Closes: #1051638)
|
||||
CVE-2023-39350 CVE-2023-39351 CVE-2023-39352 CVE-2023-39353
|
||||
CVE-2023-39354 CVE-2023-39355 CVE-2023-39356 CVE-2023-40567
|
||||
CVE-2023-40181 CVE-2023-40186 CVE-2023-40188 CVE-2023-40569
|
||||
CVE-2023-40589
|
||||
|
||||
-- Tobias Frost <tobi@debian.org> Sat, 07 Oct 2023 17:11:57 +0200
|
||||
|
||||
freerdp2 (2.3.0+dfsg1-2+deb11u1) bullseye; urgency=medium
|
||||
|
||||
[ Bernhard Miklautz ]
|
||||
* debian/rules:
|
||||
+ Disable additional debug logging. (Closes: #1006683).
|
||||
|
||||
[ Mike Gabriel ]
|
||||
* debian/patches:
|
||||
+ Add 1001_keep-symbol-DumpThreadHandles-if-debugging-is-disabled.patch.
|
||||
Keep DumpThreadHandles as a symbol even if WITH_DEBUG_THREADS is OFF.
|
||||
|
||||
-- Mike Gabriel <sunweaver@debian.org> Tue, 08 Mar 2022 08:45:48 +0100
|
||||
|
||||
freerdp2 (2.3.0+dfsg1-2) unstable; urgency=medium
|
||||
|
||||
* debian/watch:
|
||||
@ -165,6 +227,50 @@ freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-2) unstable; urgency=medium
|
||||
|
||||
-- Mike Gabriel <sunweaver@debian.org> Mon, 16 Dec 2019 11:25:24 +0100
|
||||
|
||||
freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u2) buster; urgency=medium
|
||||
|
||||
[ Bernhard Miklautz ]
|
||||
* debian/patches - security releated backports from upstream
|
||||
* Add 0003-Fixed-6007-Boundary-checks-in-rdp_read_flow_control.patch
|
||||
* Add 0004-Fixed-6009-Bounds-checks-in-autodetect_recv_bandwidt.patch
|
||||
* Add 0005-Fixed-6006-bounds-checks-in-update_read_synchronize.patch
|
||||
* Add 0006-Fixed-6005-Bounds-checks-in-update_read_bitmap_data.patch
|
||||
* Add 0007-Fixed-6011-Bounds-check-in-rdp_read_font_capability.patch
|
||||
* Add 0008-Fixed-6013-Check-new-length-is-0.patch
|
||||
* Add 0009-Fix-6010-Check-length-in-read_icon_info.patch
|
||||
* Add 0010-Use-substreams-to-parse-gcc_read_server_data_blocks.patch
|
||||
* Add 0011-Fixed-Stream_-macros-bracing-arguments.patch
|
||||
* Add 0012-Use-safe-seek-for-capability-parsing.patch
|
||||
* Add 0013-Fixed-CVE-2020-11525-Out-of-bounds-read-in-bitmap_ca.patch
|
||||
(CVE-2020-11525).
|
||||
* Add 0014-Fixed-6012-CVE-2020-11526-Out-of-bounds-read-in-upda.patch
|
||||
(CVE-2020-11526).
|
||||
* Add 0015-Fix-CVE-2020-11523-clamp-invalid-rectangles-to-size-.patch
|
||||
(CVE-2020-11523).
|
||||
* Add 0016-Fix-CVE-2020-11524-out-of-bounds-access-in-interleav.patch
|
||||
(CVE-2020-11524).
|
||||
* Add 0017-Fixed-CVE-2020-11522-Limit-number-of-DELTA_RECT-to-4.patch
|
||||
(CVE-2020-11522).
|
||||
* Add 0018-Fixed-CVE-2020-11521-Out-of-bounds-write-in-planar-c.patch
|
||||
(CVE-2020-11521).
|
||||
* Add 0019-Fixed-possible-NULL-access.patch
|
||||
* Add 0020-Check-for-int-overflow-in-gdi_InvalidateRegion.patch
|
||||
|
||||
[ Mike Gabriel ]
|
||||
* debian/patches:
|
||||
+ Add 0002_fix-channels-smartcard-fix-statusw-call.patch. Fix smartcard
|
||||
login failures. (Closes: #919281).
|
||||
|
||||
-- Mike Gabriel <sunweaver@debian.org> Mon, 01 Jun 2020 13:08:46 +0200
|
||||
|
||||
freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-1+deb10u1) buster; urgency=medium
|
||||
|
||||
* debian/patches:
|
||||
+ Add 0001_CVE-2019-17177.patch. Fix realloc return handling.
|
||||
(CVE-2019-17177).
|
||||
|
||||
-- Mike Gabriel <sunweaver@debian.org> Mon, 16 Dec 2019 11:36:02 +0100
|
||||
|
||||
freerdp2 (2.0.0~git20190204.1.2693389a+dfsg1-1) unstable; urgency=medium
|
||||
|
||||
* Import Git snapshot for 2.0.0-2693389a (post ~rc4) from upstream:
|
||||
|
||||
7
debian/control
vendored
7
debian/control
vendored
@ -6,14 +6,16 @@ Uploaders:
|
||||
Mike Gabriel <sunweaver@debian.org>,
|
||||
Bernhard Miklautz <bernhard.miklautz@shacknet.at>,
|
||||
Build-Depends:
|
||||
debhelper-compat (= 13),
|
||||
cmake,
|
||||
debhelper-compat (= 12),
|
||||
docbook-xsl,
|
||||
dpkg-dev (>= 1.16.1.1),
|
||||
libasound2-dev,
|
||||
libavcodec-dev,
|
||||
libavutil-dev,
|
||||
libcairo2-dev,
|
||||
libcups2-dev,
|
||||
libdbus-glib-1-dev,
|
||||
libgsm1-dev,
|
||||
libgstreamer1.0-dev,
|
||||
libgstreamer-plugins-base1.0-dev,
|
||||
@ -45,8 +47,7 @@ Build-Depends:
|
||||
uuid-dev,
|
||||
xmlto,
|
||||
xsltproc,
|
||||
Standards-Version: 4.5.1
|
||||
Rules-Requires-Root: no
|
||||
Standards-Version: 4.3.0
|
||||
Homepage: https://www.freerdp.com/
|
||||
Vcs-Browser: https://salsa.debian.org/debian-remote-team/freerdp2
|
||||
Vcs-Git: https://salsa.debian.org/debian-remote-team/freerdp2.git
|
||||
|
||||
171
debian/patches/0001_CVE-2019-17177.patch
vendored
Normal file
171
debian/patches/0001_CVE-2019-17177.patch
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
From fc80ab45621bd966f70594c0b7393ec005a94007 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Fri, 4 Oct 2019 14:49:30 +0200
|
||||
Subject: [PATCH] Fixed #5645: realloc return handling
|
||||
|
||||
---
|
||||
client/X11/generate_argument_docbook.c | 33 +++++++++++++++++++++-----
|
||||
libfreerdp/codec/region.c | 20 ++++++++++++----
|
||||
winpr/libwinpr/utils/lodepng/lodepng.c | 6 ++++-
|
||||
3 files changed, 48 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/client/X11/generate_argument_docbook.c
|
||||
+++ b/client/X11/generate_argument_docbook.c
|
||||
@@ -9,6 +9,7 @@
|
||||
LPSTR tr_esc_str(LPCSTR arg, bool format)
|
||||
{
|
||||
LPSTR tmp = NULL;
|
||||
+ LPSTR tmp2 = NULL;
|
||||
size_t cs = 0, x, ds, len;
|
||||
size_t s;
|
||||
|
||||
@@ -25,7 +26,12 @@
|
||||
ds = s + 1;
|
||||
|
||||
if (s)
|
||||
- tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ {
|
||||
+ tmp2 = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ if (!tmp2)
|
||||
+ free(tmp);
|
||||
+ tmp = tmp2;
|
||||
+ }
|
||||
|
||||
if (NULL == tmp)
|
||||
{
|
||||
@@ -43,7 +49,10 @@
|
||||
case '<':
|
||||
len = format ? 13 : 4;
|
||||
ds += len - 1;
|
||||
- tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ tmp2 = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ if (!tmp2)
|
||||
+ free(tmp);
|
||||
+ tmp = tmp2;
|
||||
|
||||
if (NULL == tmp)
|
||||
{
|
||||
@@ -64,7 +73,10 @@
|
||||
case '>':
|
||||
len = format ? 14 : 4;
|
||||
ds += len - 1;
|
||||
- tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ tmp2 = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ if (!tmp2)
|
||||
+ free(tmp);
|
||||
+ tmp = tmp2;
|
||||
|
||||
if (NULL == tmp)
|
||||
{
|
||||
@@ -84,7 +96,10 @@
|
||||
|
||||
case '\'':
|
||||
ds += 5;
|
||||
- tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ tmp2 = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ if (!tmp2)
|
||||
+ free(tmp);
|
||||
+ tmp = tmp2;
|
||||
|
||||
if (NULL == tmp)
|
||||
{
|
||||
@@ -102,7 +117,10 @@
|
||||
|
||||
case '"':
|
||||
ds += 5;
|
||||
- tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ tmp2 = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ if (!tmp2)
|
||||
+ free(tmp);
|
||||
+ tmp = tmp2;
|
||||
|
||||
if (NULL == tmp)
|
||||
{
|
||||
@@ -120,7 +138,10 @@
|
||||
|
||||
case '&':
|
||||
ds += 4;
|
||||
- tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ tmp2 = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
|
||||
+ if (!tmp2)
|
||||
+ free(tmp);
|
||||
+ tmp = tmp2;
|
||||
|
||||
if (NULL == tmp)
|
||||
{
|
||||
--- a/libfreerdp/codec/region.c
|
||||
+++ b/libfreerdp/codec/region.c
|
||||
@@ -469,8 +469,12 @@
|
||||
|
||||
if (finalNbRects != nbRects)
|
||||
{
|
||||
- int allocSize = sizeof(REGION16_DATA) + (finalNbRects * sizeof(RECTANGLE_16));
|
||||
- region->data = realloc(region->data, allocSize);
|
||||
+ REGION16_DATA* data;
|
||||
+ size_t allocSize = sizeof(REGION16_DATA) + (finalNbRects * sizeof(RECTANGLE_16));
|
||||
+ data = realloc(region->data, allocSize);
|
||||
+ if (!data)
|
||||
+ free(region->data);
|
||||
+ region->data = data;
|
||||
|
||||
if (!region->data)
|
||||
{
|
||||
@@ -487,6 +491,7 @@
|
||||
|
||||
BOOL region16_union_rect(REGION16* dst, const REGION16* src, const RECTANGLE_16* rect)
|
||||
{
|
||||
+ REGION16_DATA* data;
|
||||
const RECTANGLE_16* srcExtents;
|
||||
RECTANGLE_16* dstExtents;
|
||||
const RECTANGLE_16* currentBand, *endSrcRect, *nextBand;
|
||||
@@ -675,7 +680,10 @@
|
||||
dstExtents->bottom = MAX(rect->bottom, srcExtents->bottom);
|
||||
dstExtents->right = MAX(rect->right, srcExtents->right);
|
||||
newItems->size = sizeof(REGION16_DATA) + (usedRects * sizeof(RECTANGLE_16));
|
||||
- dst->data = realloc(newItems, newItems->size);
|
||||
+ data = realloc(newItems, newItems->size);
|
||||
+ if (!data)
|
||||
+ free(dst->data);
|
||||
+ dst->data = data;
|
||||
|
||||
if (!dst->data)
|
||||
{
|
||||
@@ -719,6 +727,7 @@
|
||||
|
||||
BOOL region16_intersect_rect(REGION16* dst, const REGION16* src, const RECTANGLE_16* rect)
|
||||
{
|
||||
+ REGION16_DATA* data;
|
||||
REGION16_DATA* newItems;
|
||||
const RECTANGLE_16* srcPtr, *endPtr, *srcExtents;
|
||||
RECTANGLE_16* dstPtr;
|
||||
@@ -791,7 +800,10 @@
|
||||
if (dst->data->size)
|
||||
free(dst->data);
|
||||
|
||||
- dst->data = realloc(newItems, newItems->size);
|
||||
+ data = realloc(newItems, newItems->size);
|
||||
+ if (!data)
|
||||
+ free(dst->data);
|
||||
+ dst->data = data;
|
||||
|
||||
if (!dst->data)
|
||||
{
|
||||
--- a/winpr/libwinpr/utils/lodepng/lodepng.c
|
||||
+++ b/winpr/libwinpr/utils/lodepng/lodepng.c
|
||||
@@ -840,11 +840,15 @@
|
||||
static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies,
|
||||
size_t mincodes, size_t numcodes, unsigned maxbitlen)
|
||||
{
|
||||
+ unsigned* lengths;
|
||||
unsigned error = 0;
|
||||
while(!frequencies[numcodes - 1] && numcodes > mincodes) numcodes--; /*trim zeroes*/
|
||||
tree->maxbitlen = maxbitlen;
|
||||
tree->numcodes = (unsigned)numcodes; /*number of symbols*/
|
||||
- tree->lengths = (unsigned*)realloc(tree->lengths, numcodes * sizeof(unsigned));
|
||||
+ lengths = (unsigned*)realloc(tree->lengths, numcodes * sizeof(unsigned));
|
||||
+ if (!lengths)
|
||||
+ free(tree->lengths);
|
||||
+ tree->lengths = lengths;
|
||||
if(!tree->lengths) return 83; /*alloc fail*/
|
||||
/*initialize all lengths to 0*/
|
||||
memset(tree->lengths, 0, numcodes * sizeof(unsigned));
|
||||
46
debian/patches/0002_fix-channels-smartcard-fix-statusw-call.patch
vendored
Normal file
46
debian/patches/0002_fix-channels-smartcard-fix-statusw-call.patch
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
From a311075202865d22b87ec2ea8d1e32fa11868012 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Miklautz <bernhard.miklautz@thincast.com>
|
||||
Date: Wed, 10 Jul 2019 18:36:34 +0200
|
||||
Subject: [PATCH] fix [channels/smartcard]: fix StatusW_Call
|
||||
|
||||
According to 2.2.2.18 Status_Call cbAtrLen is unused an must be ignored
|
||||
upon receipt.
|
||||
---
|
||||
channels/smartcard/client/smartcard_operations.c | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/channels/smartcard/client/smartcard_operations.c
|
||||
+++ b/channels/smartcard/client/smartcard_operations.c
|
||||
@@ -1204,15 +1204,19 @@
|
||||
Status_Call* call = operation->call;
|
||||
DWORD cbAtrLen;
|
||||
|
||||
- if (call->cbAtrLen > 32)
|
||||
- call->cbAtrLen = 32;
|
||||
+ /**
|
||||
+ * [MS-RDPESC]
|
||||
+ * According to 2.2.2.18 Status_Call cbAtrLen is unused an must be ignored upon receipt.
|
||||
+ */
|
||||
+ cbAtrLen = call->cbAtrLen = 32;
|
||||
+
|
||||
+ call->cchReaderLen;
|
||||
|
||||
if (call->fmszReaderNamesIsNULL)
|
||||
cchReaderLen = 0;
|
||||
else
|
||||
cchReaderLen = SCARD_AUTOALLOCATE;
|
||||
|
||||
- cbAtrLen = call->cbAtrLen;
|
||||
ZeroMemory(ret.pbAtr, 32);
|
||||
status = ret.ReturnCode = SCardStatusW(operation->hCard,
|
||||
call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames,
|
||||
@@ -1231,8 +1235,7 @@
|
||||
ret.cBytes = cchReaderLen;
|
||||
#endif
|
||||
|
||||
- if (call->cbAtrLen)
|
||||
- ret.cbAtrLen = cbAtrLen;
|
||||
+ ret.cbAtrLen = cbAtrLen;
|
||||
}
|
||||
|
||||
smartcard_trace_status_return(smartcard, &ret, TRUE);
|
||||
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)
|
||||
|
||||
40
debian/patches/0036-CVE-2023-39350.patch
vendored
Normal file
40
debian/patches/0036-CVE-2023-39350.patch
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
Description: Upstream fix for CVE-2023-39350 - Global-Buffer-Overflow in ncrush_decompress
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/7ece410ce5b5660b9191e1ccb6835158afa11822
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-rrrv-3w42-pffh
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From 7ece410ce5b5660b9191e1ccb6835158afa11822 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Fri, 4 Aug 2023 13:55:40 +0200
|
||||
Subject: [PATCH] [codec,rfx] fix possible out of bound read
|
||||
|
||||
Allows malicious servers to crash FreeRDP based clients
|
||||
reported by @pwn2carr
|
||||
|
||||
(cherry picked from commit a51952882f2eb3bbce6b69a7a4f9a54bf1dbb672)
|
||||
---
|
||||
libfreerdp/codec/rfx.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/libfreerdp/codec/rfx.c
|
||||
+++ b/libfreerdp/codec/rfx.c
|
||||
@@ -1106,8 +1106,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
- Stream_StaticInit(&subStream, Stream_Pointer(s), blockLen - (6 + extraBlockLen));
|
||||
- Stream_Seek(s, blockLen - (6 + extraBlockLen));
|
||||
+ const size_t blockLenNoHeader = blockLen - 6;
|
||||
+ if (blockLenNoHeader < extraBlockLen)
|
||||
+ {
|
||||
+ WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
+ "blockLen too small(%" PRIu32 "), must be >= 6 + %" PRIu16, blockLen,
|
||||
+ extraBlockLen);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ const size_t subStreamLen = blockLenNoHeader - extraBlockLen;
|
||||
+ Stream_StaticInit(&subStream, Stream_Pointer(s), subStreamLen);
|
||||
+ Stream_Seek(s, subStreamLen);
|
||||
|
||||
switch (blockType)
|
||||
{
|
||||
18
debian/patches/0037-CVE-2023-39351.patch
vendored
Normal file
18
debian/patches/0037-CVE-2023-39351.patch
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
Description: Upstream fix for CVE-2023-39351 - Null Pointer Dereference leading DOS in RemoteFX
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/99e243cdbc31f66b5c917452c8fed3276e8bdcd5
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-q9x9-cqjc-rgwq
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
--- a/libfreerdp/codec/rfx.c
|
||||
+++ b/libfreerdp/codec/rfx.c
|
||||
@@ -1235,6 +1235,11 @@
|
||||
region16_uninit(&clippingRects);
|
||||
return TRUE;
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ rfx_message_free(context, message);
|
||||
+ context->currentMessage.freeArray = TRUE;
|
||||
+ }
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
123
debian/patches/0038-CVE-2023-39352.patch
vendored
Normal file
123
debian/patches/0038-CVE-2023-39352.patch
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
Description: Upstream fix for CVE-2023-39352 - Invalid offset validation leading to Out Of Bound Write
|
||||
Backport of upstream patch, redigining WINPR_ASSERT as this was introduced
|
||||
in upstream codebase only.
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/856ecaa463e963ecfebc9734423d69139e7b3916
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-whwr-qcf2-2mvj
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From 856ecaa463e963ecfebc9734423d69139e7b3916 Mon Sep 17 00:00:00 2001
|
||||
From: houchengqiu <houchengqiu@uniontech.com>
|
||||
Date: Mon, 22 May 2023 16:03:54 +0800
|
||||
Subject: [PATCH] [libfreerdp] add bound check in gdi_SolidFill
|
||||
|
||||
In Windows remote run vulnerabillities exe program, to create
|
||||
Micorosoft::Windows::RDS::Graphics channel, case Remmina crash.
|
||||
So, add bound check, limit the size of the requested rect, no larger than the surface data buffer.
|
||||
|
||||
(cherry picked from commit 6a63441e4ee8e2bf333361f5d24156a183b14ecd)
|
||||
---
|
||||
libfreerdp/gdi/gfx.c | 68 ++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 43 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/libfreerdp/gdi/gfx.c
|
||||
+++ b/libfreerdp/gdi/gfx.c
|
||||
@@ -29,6 +29,10 @@
|
||||
#include <freerdp/gdi/gfx.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#define WINPR_ASSERT assert
|
||||
+
|
||||
#define TAG FREERDP_TAG("gdi")
|
||||
|
||||
static BOOL is_rect_valid(const RECTANGLE_16* rect, size_t width, size_t height)
|
||||
@@ -1079,6 +1083,28 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static BOOL intersect_rect(const RECTANGLE_16* rect, const gdiGfxSurface* surface,
|
||||
+ RECTANGLE_16* prect)
|
||||
+{
|
||||
+ WINPR_ASSERT(rect);
|
||||
+ WINPR_ASSERT(surface);
|
||||
+ WINPR_ASSERT(prect);
|
||||
+
|
||||
+ if (rect->left > rect->right)
|
||||
+ return FALSE;
|
||||
+ if (rect->left > surface->width)
|
||||
+ return FALSE;
|
||||
+ if (rect->top > rect->bottom)
|
||||
+ return FALSE;
|
||||
+ if (rect->top > surface->height)
|
||||
+ return FALSE;
|
||||
+ prect->left = rect->left;
|
||||
+ prect->top = rect->top;
|
||||
+ prect->right = MIN(rect->right, surface->width);
|
||||
+ prect->bottom = MIN(rect->bottom, surface->height);
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@@ -1087,40 +1113,36 @@
|
||||
static UINT gdi_SolidFill(RdpgfxClientContext* context, const RDPGFX_SOLID_FILL_PDU* solidFill)
|
||||
{
|
||||
UINT status = ERROR_INTERNAL_ERROR;
|
||||
- UINT16 index;
|
||||
- UINT32 color;
|
||||
- BYTE a, r, g, b;
|
||||
- UINT32 nWidth, nHeight;
|
||||
- RECTANGLE_16* rect;
|
||||
- gdiGfxSurface* surface;
|
||||
- RECTANGLE_16 invalidRect;
|
||||
+ BYTE a = 0;
|
||||
+ RECTANGLE_16 invalidRect = { 0 };
|
||||
rdpGdi* gdi = (rdpGdi*)context->custom;
|
||||
+
|
||||
EnterCriticalSection(&context->mux);
|
||||
- surface = (gdiGfxSurface*)context->GetSurfaceData(context, solidFill->surfaceId);
|
||||
+
|
||||
+ WINPR_ASSERT(context->GetSurfaceData);
|
||||
+ gdiGfxSurface* surface = (gdiGfxSurface*)context->GetSurfaceData(context, solidFill->surfaceId);
|
||||
|
||||
if (!surface)
|
||||
goto fail;
|
||||
|
||||
- b = solidFill->fillPixel.B;
|
||||
- g = solidFill->fillPixel.G;
|
||||
- r = solidFill->fillPixel.R;
|
||||
- /* a = solidFill->fillPixel.XA;
|
||||
- * Ignore alpha channel, this is a solid fill. */
|
||||
+ const BYTE b = solidFill->fillPixel.B;
|
||||
+ const BYTE g = solidFill->fillPixel.G;
|
||||
+ const BYTE r = solidFill->fillPixel.R;
|
||||
a = 0xFF;
|
||||
- color = FreeRDPGetColor(surface->format, r, g, b, a);
|
||||
+ const UINT32 color = FreeRDPGetColor(surface->format, r, g, b, a);
|
||||
|
||||
- for (index = 0; index < solidFill->fillRectCount; index++)
|
||||
+ for (UINT16 index = 0; index < solidFill->fillRectCount; index++)
|
||||
{
|
||||
- rect = &(solidFill->fillRects[index]);
|
||||
- nWidth = rect->right - rect->left;
|
||||
- nHeight = rect->bottom - rect->top;
|
||||
- invalidRect.left = rect->left;
|
||||
- invalidRect.top = rect->top;
|
||||
- invalidRect.right = rect->right;
|
||||
- invalidRect.bottom = rect->bottom;
|
||||
+ const RECTANGLE_16* rect = &(solidFill->fillRects[index]);
|
||||
+
|
||||
+ if (!intersect_rect(rect, surface, &invalidRect))
|
||||
+ goto fail;
|
||||
+
|
||||
+ const UINT32 nWidth = invalidRect.right - invalidRect.left;
|
||||
+ const UINT32 nHeight = invalidRect.bottom - invalidRect.top;
|
||||
|
||||
- if (!freerdp_image_fill(surface->data, surface->format, surface->scanline, rect->left,
|
||||
- rect->top, nWidth, nHeight, color))
|
||||
+ if (!freerdp_image_fill(surface->data, surface->format, surface->scanline, invalidRect.left,
|
||||
+ invalidRect.top, nWidth, nHeight, color))
|
||||
goto fail;
|
||||
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||
52
debian/patches/0039-CVE-2023-39353-part1.patch
vendored
Normal file
52
debian/patches/0039-CVE-2023-39353-part1.patch
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
Description: Upstream fix for CVE-2023-39353 - Missing offset validation leading to Out Of Bound Read
|
||||
commit 1 of 2.
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/efa0567c027239b901ccdc590b9e229e0111c68b
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-hg53-9j9h-3c8f
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From efa0567c027239b901ccdc590b9e229e0111c68b Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <anovak@thincast.com>
|
||||
Date: Sat, 5 Aug 2023 08:57:28 +0200
|
||||
Subject: [PATCH] [coded,rfx] check indices are within range
|
||||
|
||||
reported by @pwn2carr
|
||||
|
||||
(cherry picked from commit 61e17f4707cee66ecaa7519073bae74ecf0a9af4)
|
||||
---
|
||||
libfreerdp/codec/rfx.c | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c
|
||||
index 13d48c24f329..d7f0d8c65d25 100644
|
||||
--- a/libfreerdp/codec/rfx.c
|
||||
+++ b/libfreerdp/codec/rfx.c
|
||||
@@ -936,6 +936,30 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxY); /* quantIdxY (1 byte) */
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxCb); /* quantIdxCb (1 byte) */
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxCr); /* quantIdxCr (1 byte) */
|
||||
+ if (tile->quantIdxY >= context->numQuant)
|
||||
+ {
|
||||
+ WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
+ "quantIdxY %" PRIu8 " >= numQuant %" PRIu8, tile->quantIdxY,
|
||||
+ context->numQuant);
|
||||
+ rc = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (tile->quantIdxCb >= context->numQuant)
|
||||
+ {
|
||||
+ WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
+ "quantIdxCb %" PRIu8 " >= numQuant %" PRIu8, tile->quantIdxCb,
|
||||
+ context->numQuant);
|
||||
+ rc = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (tile->quantIdxCr >= context->numQuant)
|
||||
+ {
|
||||
+ WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
+ "quantIdxCr %" PRIu8 " >= numQuant %" PRIu8, tile->quantIdxCr,
|
||||
+ context->numQuant);
|
||||
+ rc = FALSE;
|
||||
+ break;
|
||||
+
|
||||
Stream_Read_UINT16(&sub, tile->xIdx); /* xIdx (2 bytes) */
|
||||
Stream_Read_UINT16(&sub, tile->yIdx); /* yIdx (2 bytes) */
|
||||
Stream_Read_UINT16(&sub, tile->YLen); /* YLen (2 bytes) */
|
||||
68
debian/patches/0039-CVE-2023-39353-part2.patch
vendored
Normal file
68
debian/patches/0039-CVE-2023-39353-part2.patch
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
Description: Upstream fix for CVE-2023-39353 - Missing offset validation leading to Out Of Bound Read
|
||||
commit 2 of 2.
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/9ed6d6baede27d5006e0e4c9bec8e506f695cb6a
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-hg53-9j9h-3c8f
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From 9ed6d6baede27d5006e0e4c9bec8e506f695cb6a Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Tue, 22 Aug 2023 11:37:57 +0200
|
||||
Subject: [PATCH] [codec,rfx] fix missing brace from broken backport
|
||||
|
||||
---
|
||||
libfreerdp/codec/rfx.c | 43 ++++++++++++++++++++----------------------
|
||||
1 file changed, 20 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c
|
||||
index d7f0d8c65d25..ccbc5afe44fa 100644
|
||||
--- a/libfreerdp/codec/rfx.c
|
||||
+++ b/libfreerdp/codec/rfx.c
|
||||
@@ -937,29 +937,26 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxCb); /* quantIdxCb (1 byte) */
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxCr); /* quantIdxCr (1 byte) */
|
||||
if (tile->quantIdxY >= context->numQuant)
|
||||
- {
|
||||
- WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
- "quantIdxY %" PRIu8 " >= numQuant %" PRIu8, tile->quantIdxY,
|
||||
- context->numQuant);
|
||||
- rc = FALSE;
|
||||
- break;
|
||||
- }
|
||||
- if (tile->quantIdxCb >= context->numQuant)
|
||||
- {
|
||||
- WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
- "quantIdxCb %" PRIu8 " >= numQuant %" PRIu8, tile->quantIdxCb,
|
||||
- context->numQuant);
|
||||
- rc = FALSE;
|
||||
- break;
|
||||
- }
|
||||
- if (tile->quantIdxCr >= context->numQuant)
|
||||
- {
|
||||
- WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
- "quantIdxCr %" PRIu8 " >= numQuant %" PRIu8, tile->quantIdxCr,
|
||||
- context->numQuant);
|
||||
- rc = FALSE;
|
||||
- break;
|
||||
-
|
||||
+ {
|
||||
+ WLog_Print(context->priv->log, WLOG_ERROR, "quantIdxY %" PRIu8 " >= numQuant %" PRIu8,
|
||||
+ tile->quantIdxY, context->numQuant);
|
||||
+ rc = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (tile->quantIdxCb >= context->numQuant)
|
||||
+ {
|
||||
+ WLog_Print(context->priv->log, WLOG_ERROR, "quantIdxCb %" PRIu8 " >= numQuant %" PRIu8,
|
||||
+ tile->quantIdxCb, context->numQuant);
|
||||
+ rc = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (tile->quantIdxCr >= context->numQuant)
|
||||
+ {
|
||||
+ WLog_Print(context->priv->log, WLOG_ERROR, "quantIdxCr %" PRIu8 " >= numQuant %" PRIu8,
|
||||
+ tile->quantIdxCr, context->numQuant);
|
||||
+ rc = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
Stream_Read_UINT16(&sub, tile->xIdx); /* xIdx (2 bytes) */
|
||||
Stream_Read_UINT16(&sub, tile->yIdx); /* yIdx (2 bytes) */
|
||||
Stream_Read_UINT16(&sub, tile->YLen); /* YLen (2 bytes) */
|
||||
264
debian/patches/0040-CVE-2023-39354-part1.patch
vendored
Normal file
264
debian/patches/0040-CVE-2023-39354-part1.patch
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
Description: Upstream fix for CVE-2023-39354 - Out-Of-Bounds Read in nsc_rle_decompress_data
|
||||
commit 1 of 2.
|
||||
Backported changes required, e.g Stream_CheckAndLogRequiredLengthWLogEx() and WPR_ASSERT substituted.
|
||||
with aseert()
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/82ac0164f330c08ddd9a6ef6f3dbf846c4b79def
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-c3r2-pxxp-f8r6
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From 82ac0164f330c08ddd9a6ef6f3dbf846c4b79def Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <anovak@thincast.com>
|
||||
Date: Sat, 5 Aug 2023 10:53:29 +0200
|
||||
Subject: [PATCH] [codec,nsc] fix missing plane length check
|
||||
|
||||
reported by @pwn2carr
|
||||
|
||||
(cherry picked from commit 89cd622426b3fcac64b9203e69f9f407cc19760e)
|
||||
---
|
||||
libfreerdp/codec/nsc.c | 71 +++++++++++++++++++++---------------------
|
||||
1 file changed, 36 insertions(+), 35 deletions(-)
|
||||
|
||||
--- a/libfreerdp/codec/nsc.c
|
||||
+++ b/libfreerdp/codec/nsc.c
|
||||
@@ -30,6 +30,9 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
+#include <assert.h>
|
||||
+#include <winpr/stream.h>
|
||||
+
|
||||
#include <freerdp/codec/nsc.h>
|
||||
#include <freerdp/codec/color.h>
|
||||
|
||||
@@ -38,6 +41,14 @@
|
||||
|
||||
#include "nsc_sse2.h"
|
||||
|
||||
+#define WINPR_ASSERT assert
|
||||
+
|
||||
+#if !defined(Stream_CheckAndLogRequiredLengthWLog)
|
||||
+#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \
|
||||
+ Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, "%s(%s:%d)", __FUNCTION__, \
|
||||
+ __FILE__, __LINE__)
|
||||
+#endif
|
||||
+
|
||||
#ifndef NSC_INIT_SIMD
|
||||
#define NSC_INIT_SIMD(_nsc_context) \
|
||||
do \
|
||||
@@ -175,20 +186,16 @@
|
||||
|
||||
static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
{
|
||||
- UINT16 i;
|
||||
- BYTE* rle;
|
||||
- UINT32 planeSize;
|
||||
- UINT32 originalSize;
|
||||
-
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
- rle = context->Planes;
|
||||
+ BYTE* rle = context->Planes;
|
||||
+ WINPR_ASSERT(rle);
|
||||
|
||||
- for (i = 0; i < 4; i++)
|
||||
+ for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
- originalSize = context->OrgByteCount[i];
|
||||
- planeSize = context->PlaneByteCount[i];
|
||||
+ const UINT32 originalSize = context->OrgByteCount[i];
|
||||
+ const UINT32 planeSize = context->PlaneByteCount[i];
|
||||
|
||||
if (planeSize == 0)
|
||||
{
|
||||
@@ -219,64 +226,63 @@
|
||||
|
||||
static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
{
|
||||
- int i;
|
||||
-
|
||||
- if (Stream_GetRemainingLength(s) < 20)
|
||||
+ WINPR_ASSERT(context);
|
||||
+ WINPR_ASSERT(context->priv);
|
||||
+ if (!Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, 20))
|
||||
return FALSE;
|
||||
|
||||
- for (i = 0; i < 4; i++)
|
||||
+ size_t total = 0;
|
||||
+ for (size_t i = 0; i < 4; i++)
|
||||
+ {
|
||||
Stream_Read_UINT32(s, context->PlaneByteCount[i]);
|
||||
+ total += context->PlaneByteCount[i];
|
||||
+ }
|
||||
|
||||
Stream_Read_UINT8(s, context->ColorLossLevel); /* ColorLossLevel (1 byte) */
|
||||
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
Stream_Seek(s, 2); /* Reserved (2 bytes) */
|
||||
context->Planes = Stream_Pointer(s);
|
||||
- return TRUE;
|
||||
+ return Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, total);
|
||||
}
|
||||
|
||||
static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
{
|
||||
- int i;
|
||||
- UINT32 length;
|
||||
- UINT32 tempWidth;
|
||||
- UINT32 tempHeight;
|
||||
-
|
||||
if (!nsc_stream_initialize(context, s))
|
||||
return FALSE;
|
||||
|
||||
- length = context->width * context->height * 4;
|
||||
+ const size_t blength = context->width * context->height * 4;
|
||||
|
||||
if (!context->BitmapData)
|
||||
{
|
||||
- context->BitmapData = calloc(1, length + 16);
|
||||
+ context->BitmapData = calloc(1, blength + 16);
|
||||
|
||||
if (!context->BitmapData)
|
||||
return FALSE;
|
||||
|
||||
- context->BitmapDataLength = length;
|
||||
+ context->BitmapDataLength = blength;
|
||||
}
|
||||
- else if (length > context->BitmapDataLength)
|
||||
+ else if (blength > context->BitmapDataLength)
|
||||
{
|
||||
void* tmp;
|
||||
- tmp = realloc(context->BitmapData, length + 16);
|
||||
+ tmp = realloc(context->BitmapData, blength + 16);
|
||||
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
|
||||
context->BitmapData = tmp;
|
||||
- context->BitmapDataLength = length;
|
||||
+ context->BitmapDataLength = blength;
|
||||
}
|
||||
|
||||
- tempWidth = ROUND_UP_TO(context->width, 8);
|
||||
- tempHeight = ROUND_UP_TO(context->height, 2);
|
||||
+ const UINT32 tempWidth = ROUND_UP_TO(context->width, 8);
|
||||
+ const UINT32 tempHeight = ROUND_UP_TO(context->height, 2);
|
||||
/* The maximum length a decoded plane can reach in all cases */
|
||||
- length = tempWidth * tempHeight;
|
||||
+ const size_t plength = tempWidth * tempHeight;
|
||||
|
||||
- if (length > context->priv->PlaneBuffersLength)
|
||||
+ if (plength > context->priv->PlaneBuffersLength)
|
||||
{
|
||||
- for (i = 0; i < 4; i++)
|
||||
+ for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
- void* tmp = (BYTE*)realloc(context->priv->PlaneBuffers[i], length);
|
||||
+ void* tmp = (BYTE*)realloc(context->priv->PlaneBuffers[i], plength);
|
||||
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
@@ -284,13 +290,11 @@
|
||||
context->priv->PlaneBuffers[i] = tmp;
|
||||
}
|
||||
|
||||
- context->priv->PlaneBuffersLength = length;
|
||||
+ context->priv->PlaneBuffersLength = plength;
|
||||
}
|
||||
|
||||
- for (i = 0; i < 4; i++)
|
||||
- {
|
||||
+ for (size_t i = 0; i < 4; i++)
|
||||
context->OrgByteCount[i] = context->width * context->height;
|
||||
- }
|
||||
|
||||
if (context->ChromaSubsamplingLevel)
|
||||
{
|
||||
--- a/winpr/include/winpr/stream.h
|
||||
+++ b/winpr/include/winpr/stream.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/endian.h>
|
||||
#include <winpr/synch.h>
|
||||
+#include <winpr/wlog.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@@ -56,6 +57,14 @@
|
||||
WINPR_API void Stream_StaticInit(wStream* s, BYTE* buffer, size_t size);
|
||||
WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
|
||||
|
||||
+
|
||||
+ WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s,
|
||||
+ size_t nmemb, size_t size,
|
||||
+ const char* fmt, ...);
|
||||
+ WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s,
|
||||
+ size_t nmemb, size_t size,
|
||||
+ const char* fmt, va_list args);
|
||||
+
|
||||
static INLINE void Stream_Seek(wStream* s, size_t _offset)
|
||||
{
|
||||
s->pointer += (_offset);
|
||||
--- a/winpr/libwinpr/utils/stream.c
|
||||
+++ b/winpr/libwinpr/utils/stream.c
|
||||
@@ -26,6 +26,15 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
+#include <winpr/wlog.h>
|
||||
+
|
||||
+#if defined(__GNUC__) || defined(__clang__)
|
||||
+#define WINPR_ATTR_FORMAT_ARG(pos, args) __attribute__((__format__(__printf__, pos, args)))
|
||||
+#else
|
||||
+#define WINPR_ATTR_FORMAT_ARG(pos, args)
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
BOOL Stream_EnsureCapacity(wStream* s, size_t size)
|
||||
{
|
||||
if (s->capacity < size)
|
||||
@@ -132,3 +141,46 @@
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
+
|
||||
+BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, size_t nmemb,
|
||||
+ size_t size, const char* fmt, ...)
|
||||
+{
|
||||
+ assert(size > 0);
|
||||
+ const size_t actual = Stream_GetRemainingLength(s) / size;
|
||||
+
|
||||
+ if (actual < nmemb)
|
||||
+ {
|
||||
+ va_list args;
|
||||
+
|
||||
+ va_start(args, fmt);
|
||||
+ Stream_CheckAndLogRequiredLengthWLogExVa(log, level, s, nmemb, size, fmt, args);
|
||||
+ va_end(args);
|
||||
+
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+WINPR_ATTR_FORMAT_ARG(6, 0)
|
||||
+BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s, size_t nmemb,
|
||||
+ size_t size, const char* fmt, va_list args)
|
||||
+{
|
||||
+ assert(size > 0);
|
||||
+ const size_t actual = Stream_GetRemainingLength(s) / size;
|
||||
+
|
||||
+ if (actual < nmemb)
|
||||
+ {
|
||||
+ char prefix[1024] = { 0 };
|
||||
+
|
||||
+ vsnprintf(prefix, sizeof(prefix), fmt, args);
|
||||
+
|
||||
+ WLog_Print(log, level,
|
||||
+ "[%s] invalid length, got %" PRIuz ", require at least %" PRIuz
|
||||
+ " [element size=%" PRIuz "]",
|
||||
+ prefix, actual, nmemb, size);
|
||||
+ winpr_log_backtrace_ex(log, level, 20);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
131
debian/patches/0040-CVE-2023-39354-part2.patch
vendored
Normal file
131
debian/patches/0040-CVE-2023-39354-part2.patch
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
Description: Upstream fix for CVE-2023-39354 - Out-Of-Bounds Read in nsc_rle_decompress_data
|
||||
commit 2 of 2.
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/9a1ee1bae5a9561f5031a7b69129f10458b62d4a
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-c3r2-pxxp-f8r6
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From 9a1ee1bae5a9561f5031a7b69129f10458b62d4a Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Tue, 22 Aug 2023 10:48:57 +0200
|
||||
Subject: [PATCH] [codec,nsc] fix input length validation
|
||||
|
||||
(cherry picked from commit e6bb37bea1a645610cc7e030e11fa3ec9e758dc9)
|
||||
---
|
||||
libfreerdp/codec/nsc.c | 32 ++++++++++++++++++++++++++++----
|
||||
libfreerdp/codec/nsc_types.h | 1 +
|
||||
2 files changed, 29 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/libfreerdp/codec/nsc.c
|
||||
+++ b/libfreerdp/codec/nsc.c
|
||||
@@ -122,12 +122,17 @@
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalSize)
|
||||
+static BOOL nsc_rle_decode(const BYTE* in, size_t inSize, BYTE* out, UINT32 outSize,
|
||||
+ UINT32 originalSize)
|
||||
{
|
||||
UINT32 left = originalSize;
|
||||
|
||||
while (left > 4)
|
||||
{
|
||||
+ if (inSize < 1)
|
||||
+ return FALSE;
|
||||
+ inSize--;
|
||||
+
|
||||
const BYTE value = *in++;
|
||||
UINT32 len = 0;
|
||||
|
||||
@@ -140,17 +145,26 @@
|
||||
*out++ = value;
|
||||
left--;
|
||||
}
|
||||
+ else if (inSize < 1)
|
||||
+ return FALSE;
|
||||
else if (value == *in)
|
||||
{
|
||||
+ inSize--;
|
||||
in++;
|
||||
|
||||
- if (*in < 0xFF)
|
||||
+ if (inSize < 1)
|
||||
+ return FALSE;
|
||||
+ else if (*in < 0xFF)
|
||||
{
|
||||
+ inSize--;
|
||||
len = (UINT32)*in++;
|
||||
len += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
+ if (inSize < 5)
|
||||
+ return FALSE;
|
||||
+ inSize -= 5;
|
||||
in++;
|
||||
len = ((UINT32)(*in++));
|
||||
len |= ((UINT32)(*in++)) << 8U;
|
||||
@@ -180,6 +194,8 @@
|
||||
if ((outSize < 4) || (left < 4))
|
||||
return FALSE;
|
||||
|
||||
+ if (inSize < 4)
|
||||
+ return FALSE;
|
||||
memcpy(out, in, 4);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -189,7 +205,8 @@
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
- BYTE* rle = context->Planes;
|
||||
+ const BYTE* rle = context->Planes;
|
||||
+ size_t rleSize = context->PlanesSize;
|
||||
WINPR_ASSERT(rle);
|
||||
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
@@ -197,6 +214,9 @@
|
||||
const UINT32 originalSize = context->OrgByteCount[i];
|
||||
const UINT32 planeSize = context->PlaneByteCount[i];
|
||||
|
||||
+ if (rleSize < planeSize)
|
||||
+ return FALSE;
|
||||
+
|
||||
if (planeSize == 0)
|
||||
{
|
||||
if (context->priv->PlaneBuffersLength < originalSize)
|
||||
@@ -206,7 +226,7 @@
|
||||
}
|
||||
else if (planeSize < originalSize)
|
||||
{
|
||||
- if (!nsc_rle_decode(rle, context->priv->PlaneBuffers[i],
|
||||
+ if (!nsc_rle_decode(rle, rleSize, context->priv->PlaneBuffers[i],
|
||||
context->priv->PlaneBuffersLength, originalSize))
|
||||
return FALSE;
|
||||
}
|
||||
@@ -215,6 +235,9 @@
|
||||
if (context->priv->PlaneBuffersLength < originalSize)
|
||||
return FALSE;
|
||||
|
||||
+ if (rleSize < originalSize)
|
||||
+ return FALSE;
|
||||
+
|
||||
CopyMemory(context->priv->PlaneBuffers[i], rle, originalSize);
|
||||
}
|
||||
|
||||
@@ -242,6 +265,7 @@
|
||||
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
Stream_Seek(s, 2); /* Reserved (2 bytes) */
|
||||
context->Planes = Stream_Pointer(s);
|
||||
+ context->PlanesSize = total;
|
||||
return Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, total);
|
||||
}
|
||||
|
||||
--- a/libfreerdp/codec/nsc_types.h
|
||||
+++ b/libfreerdp/codec/nsc_types.h
|
||||
@@ -61,6 +61,7 @@
|
||||
UINT32 BitmapDataLength;
|
||||
|
||||
BYTE* Planes;
|
||||
+ size_t PlanesSize;
|
||||
UINT32 PlaneByteCount[4];
|
||||
UINT32 ColorLossLevel;
|
||||
UINT32 ChromaSubsamplingLevel;
|
||||
103
debian/patches/0041-CVE-2023-39355.patch
vendored
Normal file
103
debian/patches/0041-CVE-2023-39355.patch
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
Description: Upstream fix for CVE-2023-39355 - Use-After-Free in RDPGFX_CMDID_RESETGRAPHICS
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/d6f9d33a7db0b346195b6a15b5b99944ba41beee
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-hvwj-vmg6-2f5h
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From d6f9d33a7db0b346195b6a15b5b99944ba41beee Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <anovak@thincast.com>
|
||||
Date: Sat, 5 Aug 2023 10:15:41 +0200
|
||||
Subject: [PATCH] [codec,planar] fix reset
|
||||
|
||||
---
|
||||
libfreerdp/codec/planar.c | 62 ++++++++++++++++++++++-----------------
|
||||
1 file changed, 35 insertions(+), 27 deletions(-)
|
||||
|
||||
--- a/libfreerdp/codec/planar.c
|
||||
+++ b/libfreerdp/codec/planar.c
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <freerdp/codec/bitmap.h>
|
||||
#include <freerdp/codec/planar.h>
|
||||
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
#define TAG FREERDP_TAG("codec")
|
||||
|
||||
static INLINE UINT32 planar_invert_format(BITMAP_PLANAR_CONTEXT* planar, BOOL alpha,
|
||||
@@ -847,6 +849,9 @@
|
||||
{
|
||||
BYTE* rleBuffer[4] = { 0 };
|
||||
|
||||
+ if (!planar->rlePlanesBuffer)
|
||||
+ return FALSE;
|
||||
+
|
||||
rleBuffer[3] = planar->rlePlanesBuffer; /* AlphaPlane */
|
||||
rleBuffer[0] = rleBuffer[3] + planeSize; /* LumaOrRedPlane */
|
||||
rleBuffer[1] = rleBuffer[0] + planeSize; /* OrangeChromaOrGreenPlane */
|
||||
@@ -1486,27 +1491,49 @@
|
||||
context->maxHeight = height;
|
||||
context->maxPlaneSize = context->maxWidth * context->maxHeight;
|
||||
context->nTempStep = context->maxWidth * 4;
|
||||
- free(context->planesBuffer);
|
||||
- free(context->pTempData);
|
||||
- free(context->deltaPlanesBuffer);
|
||||
- free(context->rlePlanesBuffer);
|
||||
- context->planesBuffer = calloc(context->maxPlaneSize, 4);
|
||||
- context->pTempData = calloc(context->maxPlaneSize, 6);
|
||||
- context->deltaPlanesBuffer = calloc(context->maxPlaneSize, 4);
|
||||
- context->rlePlanesBuffer = calloc(context->maxPlaneSize, 4);
|
||||
|
||||
- if (!context->planesBuffer || !context->pTempData || !context->deltaPlanesBuffer ||
|
||||
- !context->rlePlanesBuffer)
|
||||
- return FALSE;
|
||||
+ memset(context->planes, 0, sizeof(context->planes));
|
||||
+ memset(context->rlePlanes, 0, sizeof(context->rlePlanes));
|
||||
+ memset(context->deltaPlanes, 0, sizeof(context->deltaPlanes));
|
||||
+
|
||||
+ free(context->planesBuffer); context->planesBuffer = NULL;
|
||||
+ free(context->pTempData); context->pTempData = NULL;
|
||||
+ free(context->deltaPlanesBuffer); context->deltaPlanesBuffer = NULL;
|
||||
+ free(context->rlePlanesBuffer); context->rlePlanesBuffer = NULL;
|
||||
+
|
||||
+ if (context->maxPlaneSize > 0)
|
||||
+ {
|
||||
+ unsigned int err = 0;
|
||||
+ err = posix_memalign(&context->planesBuffer, 32, context->maxPlaneSize * 4);
|
||||
+ memset(context->planesBuffer, 0, context->maxPlaneSize * 4);
|
||||
+
|
||||
+ err |= posix_memalign(&context->pTempData, 32, context->maxPlaneSize * 6);
|
||||
+ memset(context->pTempData, 0, context->maxPlaneSize * 6);
|
||||
+
|
||||
+ err |= posix_memalign(&context->deltaPlanesBuffer, 32, context->maxPlaneSize * 4);
|
||||
+ memset(context->deltaPlanesBuffer, 0, context->maxPlaneSize * 4);
|
||||
+
|
||||
+ err |= posix_memalign(&context->rlePlanesBuffer, 32, context->maxPlaneSize * 4);
|
||||
+ memset(context->rlePlanesBuffer, 0, context->maxPlaneSize * 4);
|
||||
+
|
||||
+ if (err || !context->planesBuffer || !context->pTempData || !context->deltaPlanesBuffer ||
|
||||
+ !context->rlePlanesBuffer){
|
||||
+ free(context->planesBuffer); context->planesBuffer = NULL;
|
||||
+ free(context->pTempData); context->pTempData = NULL;
|
||||
+ free(context->deltaPlanesBuffer); context->deltaPlanesBuffer = NULL;
|
||||
+ free(context->rlePlanesBuffer); context->rlePlanesBuffer = NULL;
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
- context->planes[0] = &context->planesBuffer[context->maxPlaneSize * 0];
|
||||
- context->planes[1] = &context->planesBuffer[context->maxPlaneSize * 1];
|
||||
- context->planes[2] = &context->planesBuffer[context->maxPlaneSize * 2];
|
||||
- context->planes[3] = &context->planesBuffer[context->maxPlaneSize * 3];
|
||||
- context->deltaPlanes[0] = &context->deltaPlanesBuffer[context->maxPlaneSize * 0];
|
||||
- context->deltaPlanes[1] = &context->deltaPlanesBuffer[context->maxPlaneSize * 1];
|
||||
- context->deltaPlanes[2] = &context->deltaPlanesBuffer[context->maxPlaneSize * 2];
|
||||
- context->deltaPlanes[3] = &context->deltaPlanesBuffer[context->maxPlaneSize * 3];
|
||||
+ context->planes[0] = &context->planesBuffer[context->maxPlaneSize * 0];
|
||||
+ context->planes[1] = &context->planesBuffer[context->maxPlaneSize * 1];
|
||||
+ context->planes[2] = &context->planesBuffer[context->maxPlaneSize * 2];
|
||||
+ context->planes[3] = &context->planesBuffer[context->maxPlaneSize * 3];
|
||||
+ context->deltaPlanes[0] = &context->deltaPlanesBuffer[context->maxPlaneSize * 0];
|
||||
+ context->deltaPlanes[1] = &context->deltaPlanesBuffer[context->maxPlaneSize * 1];
|
||||
+ context->deltaPlanes[2] = &context->deltaPlanesBuffer[context->maxPlaneSize * 2];
|
||||
+ context->deltaPlanes[3] = &context->deltaPlanesBuffer[context->maxPlaneSize * 3];
|
||||
+ }
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
82
debian/patches/0042-CVE-2023-39356-part1.patch
vendored
Normal file
82
debian/patches/0042-CVE-2023-39356-part1.patch
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
Description: Upstream fix for CVE-2023-39356 - Missing offset validation leading to Out-of-Bounds Read in gdi_multi_opaque_rect
|
||||
commit 1 of 2.
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/889348a86e49bc8f1351ed6496d847b32db5f86e
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-q5v5-qhj5-mh6m
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From 889348a86e49bc8f1351ed6496d847b32db5f86e Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <anovak@thincast.com>
|
||||
Date: Sat, 5 Aug 2023 11:31:08 +0200
|
||||
Subject: [PATCH] [core,orders] fix checks for multi opaque rect
|
||||
|
||||
(cherry picked from commit 567847066278ec112abb99707902818b282059ad)
|
||||
---
|
||||
libfreerdp/core/orders.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/libfreerdp/core/orders.c
|
||||
+++ b/libfreerdp/core/orders.c
|
||||
@@ -28,6 +28,9 @@
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/crt.h>
|
||||
|
||||
+#include <assert.h>
|
||||
+#define WINPR_ASSERT assert
|
||||
+
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/graphics.h>
|
||||
@@ -1390,7 +1393,7 @@
|
||||
return update_read_delta_rects(s, multi_dstblt->rectangles, &multi_dstblt->numRectangles);
|
||||
}
|
||||
|
||||
- return TRUE;
|
||||
+ return multi_dstblt->numRectangles == 0;
|
||||
}
|
||||
static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_PATBLT_ORDER* multi_patblt)
|
||||
@@ -1420,12 +1423,18 @@
|
||||
if (!update_read_delta_rects(s, multi_patblt->rectangles, &multi_patblt->numRectangles))
|
||||
return FALSE;
|
||||
}
|
||||
+ else if (multi_patblt->numRectangles != 0)
|
||||
+ return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_SCRBLT_ORDER* multi_scrblt)
|
||||
{
|
||||
+ WINPR_ASSERT(orderInfo);
|
||||
+ WINPR_ASSERT(multi_scrblt);
|
||||
+
|
||||
+ multi_scrblt->numRectangles = 0;
|
||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_scrblt->nLeftRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 2, &multi_scrblt->nTopRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 3, &multi_scrblt->nWidth, FALSE) ||
|
||||
@@ -1445,7 +1454,7 @@
|
||||
return update_read_delta_rects(s, multi_scrblt->rectangles, &multi_scrblt->numRectangles);
|
||||
}
|
||||
|
||||
- return TRUE;
|
||||
+ return multi_scrblt->numRectangles == 0;
|
||||
}
|
||||
static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
|
||||
@@ -1497,7 +1506,7 @@
|
||||
&multi_opaque_rect->numRectangles);
|
||||
}
|
||||
|
||||
- return TRUE;
|
||||
+ return multi_opaque_rect->numRectangles == 0;
|
||||
}
|
||||
static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
|
||||
@@ -1520,7 +1529,7 @@
|
||||
&multi_draw_nine_grid->nDeltaEntries);
|
||||
}
|
||||
|
||||
- return TRUE;
|
||||
+ return multi_draw_nine_grid->nDeltaEntries == 0;
|
||||
}
|
||||
static BOOL update_read_line_to_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
LINE_TO_ORDER* line_to)
|
||||
246
debian/patches/0043-CVE-2023-39356-part2.patch
vendored
Normal file
246
debian/patches/0043-CVE-2023-39356-part2.patch
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
Description: Upstream fix for CVE-2023-39356 - Missing offset validation leading to Out-of-Bounds Read in gdi_multi_opaque_rect
|
||||
commit 2 of 2.
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/23db2f4e6ba71f1c10c543f24de595d7340adb46
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-q5v5-qhj5-mh6m
|
||||
From 23db2f4e6ba71f1c10c543f24de595d7340adb46 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Mon, 4 Sep 2023 09:43:32 +0200
|
||||
Subject: [PATCH] [core,orders] fix reading order number field
|
||||
|
||||
the field for delta rectangles/points/... are only transmitted if they
|
||||
changed from the previous order of the same type. So keep the original
|
||||
value and update only if a new one is read.
|
||||
|
||||
(cherry picked from commit 5b7cf4acc6b4138c513287a2eaa2c7fb9dfbf5c8)
|
||||
---
|
||||
libfreerdp/core/orders.c | 97 +++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 85 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/libfreerdp/core/orders.c
|
||||
+++ b/libfreerdp/core/orders.c
|
||||
@@ -1376,12 +1376,13 @@
|
||||
static BOOL update_read_multi_dstblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_DSTBLT_ORDER* multi_dstblt)
|
||||
{
|
||||
+ UINT32 numRectangles = multi_dstblt->numRectangles;
|
||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_dstblt->nLeftRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 2, &multi_dstblt->nTopRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 3, &multi_dstblt->nWidth, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 4, &multi_dstblt->nHeight, FALSE) ||
|
||||
!read_order_field_byte(orderInfo, s, 5, &multi_dstblt->bRop, TRUE) ||
|
||||
- !read_order_field_byte(orderInfo, s, 6, &multi_dstblt->numRectangles, TRUE))
|
||||
+ !read_order_field_byte(orderInfo, s, 6, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
||||
@@ -1389,12 +1390,21 @@
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
+ multi_dstblt->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_dstblt->cbData);
|
||||
return update_read_delta_rects(s, multi_dstblt->rectangles, &multi_dstblt->numRectangles);
|
||||
}
|
||||
-
|
||||
- return multi_dstblt->numRectangles == 0;
|
||||
+ if (numRectangles > multi_dstblt->numRectangles)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
+ multi_dstblt->numRectangles);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ multi_dstblt->numRectangles = numRectangles;
|
||||
+ return TRUE;
|
||||
}
|
||||
+
|
||||
static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_PATBLT_ORDER* multi_patblt)
|
||||
{
|
||||
@@ -1410,7 +1420,8 @@
|
||||
if (!update_read_brush(s, &multi_patblt->brush, orderInfo->fieldFlags >> 7))
|
||||
return FALSE;
|
||||
|
||||
- if (!read_order_field_byte(orderInfo, s, 13, &multi_patblt->numRectangles, TRUE))
|
||||
+ UINT32 numRectangles = multi_patblt->numRectangles;
|
||||
+ if (!read_order_field_byte(orderInfo, s, 13, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_14) != 0)
|
||||
@@ -1418,13 +1429,21 @@
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
+ multi_patblt->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_patblt->cbData);
|
||||
|
||||
if (!update_read_delta_rects(s, multi_patblt->rectangles, &multi_patblt->numRectangles))
|
||||
return FALSE;
|
||||
}
|
||||
- else if (multi_patblt->numRectangles != 0)
|
||||
+
|
||||
+ if (numRectangles > multi_patblt->numRectangles)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
+ multi_patblt->numRectangles);
|
||||
return FALSE;
|
||||
+ }
|
||||
+ multi_patblt->numRectangles = numRectangles;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1434,7 +1453,7 @@
|
||||
WINPR_ASSERT(orderInfo);
|
||||
WINPR_ASSERT(multi_scrblt);
|
||||
|
||||
- multi_scrblt->numRectangles = 0;
|
||||
+ UINT32 numRectangles = multi_scrblt->numRectangles;
|
||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_scrblt->nLeftRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 2, &multi_scrblt->nTopRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 3, &multi_scrblt->nWidth, FALSE) ||
|
||||
@@ -1442,7 +1461,7 @@
|
||||
!read_order_field_byte(orderInfo, s, 5, &multi_scrblt->bRop, TRUE) ||
|
||||
!read_order_field_coord(orderInfo, s, 6, &multi_scrblt->nXSrc, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 7, &multi_scrblt->nYSrc, FALSE) ||
|
||||
- !read_order_field_byte(orderInfo, s, 8, &multi_scrblt->numRectangles, TRUE))
|
||||
+ !read_order_field_byte(orderInfo, s, 8, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
||||
@@ -1450,11 +1469,21 @@
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
+ multi_scrblt->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_scrblt->cbData);
|
||||
return update_read_delta_rects(s, multi_scrblt->rectangles, &multi_scrblt->numRectangles);
|
||||
}
|
||||
|
||||
- return multi_scrblt->numRectangles == 0;
|
||||
+ if (numRectangles > multi_scrblt->numRectangles)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
+ multi_scrblt->numRectangles);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ multi_scrblt->numRectangles = numRectangles;
|
||||
+
|
||||
+ return TRUE;
|
||||
}
|
||||
static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
|
||||
@@ -1493,7 +1522,8 @@
|
||||
multi_opaque_rect->color = (multi_opaque_rect->color & 0x0000FFFF) | ((UINT32)byte << 16);
|
||||
}
|
||||
|
||||
- if (!read_order_field_byte(orderInfo, s, 8, &multi_opaque_rect->numRectangles, TRUE))
|
||||
+ UINT32 numRectangles = multi_opaque_rect->numRectangles;
|
||||
+ if (!read_order_field_byte(orderInfo, s, 8, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
||||
@@ -1501,22 +1531,32 @@
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
+ multi_opaque_rect->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_opaque_rect->cbData);
|
||||
return update_read_delta_rects(s, multi_opaque_rect->rectangles,
|
||||
&multi_opaque_rect->numRectangles);
|
||||
}
|
||||
+ if (numRectangles > multi_opaque_rect->numRectangles)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
+ multi_opaque_rect->numRectangles);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ multi_opaque_rect->numRectangles = numRectangles;
|
||||
|
||||
- return multi_opaque_rect->numRectangles == 0;
|
||||
+ return TRUE;
|
||||
}
|
||||
static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
|
||||
{
|
||||
+ UINT32 nDeltaEntries = multi_draw_nine_grid->nDeltaEntries;
|
||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_draw_nine_grid->srcLeft, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 2, &multi_draw_nine_grid->srcTop, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 3, &multi_draw_nine_grid->srcRight, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 4, &multi_draw_nine_grid->srcBottom, FALSE) ||
|
||||
!read_order_field_uint16(orderInfo, s, 5, &multi_draw_nine_grid->bitmapId, TRUE) ||
|
||||
- !read_order_field_byte(orderInfo, s, 6, &multi_draw_nine_grid->nDeltaEntries, TRUE))
|
||||
+ !read_order_field_byte(orderInfo, s, 6, &nDeltaEntries, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
||||
@@ -1524,12 +1564,22 @@
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
+ multi_draw_nine_grid->nDeltaEntries = nDeltaEntries;
|
||||
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);
|
||||
}
|
||||
|
||||
- return multi_draw_nine_grid->nDeltaEntries == 0;
|
||||
+ if (nDeltaEntries > multi_draw_nine_grid->nDeltaEntries)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s nDeltaEntries %" PRIu32 " > %" PRIu32, orderName, nDeltaEntries,
|
||||
+ multi_draw_nine_grid->nDeltaEntries);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ multi_draw_nine_grid->nDeltaEntries = nDeltaEntries;
|
||||
+
|
||||
+ return TRUE;
|
||||
}
|
||||
static BOOL update_read_line_to_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
LINE_TO_ORDER* line_to)
|
||||
@@ -1619,6 +1669,14 @@
|
||||
return update_read_delta_points(s, polyline->points, polyline->numDeltaEntries,
|
||||
polyline->xStart, polyline->yStart);
|
||||
}
|
||||
+ if (new_num > polyline->numDeltaEntries)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s numDeltaEntries %" PRIu32 " > %" PRIu32, orderName, new_num,
|
||||
+ polyline->numDeltaEntries);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ polyline->numDeltaEntries = new_num;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1944,6 +2002,13 @@
|
||||
return update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints,
|
||||
polygon_sc->xStart, polygon_sc->yStart);
|
||||
}
|
||||
+ if (num > polygon_sc->numPoints)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s numPoints %" PRIu32 " > %" PRIu32, orderName, num, polygon_sc->numPoints);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ polygon_sc->numPoints = num;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1989,6 +2054,14 @@
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ if (num > polygon_cb->numPoints)
|
||||
+ {
|
||||
+ const char* orderName = __func__;
|
||||
+ WLog_ERR(TAG, "%s numPoints %" PRIu32 " > %" PRIu32, orderName, num, polygon_cb->numPoints);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ polygon_cb->numPoints = num;
|
||||
+
|
||||
polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE;
|
||||
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
|
||||
return TRUE;
|
||||
167
debian/patches/0044-CVE-2023-40567.patch
vendored
Normal file
167
debian/patches/0044-CVE-2023-40567.patch
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
Description: Upstream fix for CVE-2023-40567 - Out-Of-Bounds Write in clear_decompress_bands_data
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/bacb8c016ef72aa767760b6b01d15500aee9d59a
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-2w9f-8wg4-8jfp
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From bacb8c016ef72aa767760b6b01d15500aee9d59a Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Tue, 22 Aug 2023 14:44:57 +0200
|
||||
Subject: [PATCH] [codec,clear] fix missing bounds checks
|
||||
|
||||
(cherry picked from commit 680619fc48f40d458c9614b47bfde61226a324aa)
|
||||
---
|
||||
libfreerdp/codec/clear.c | 59 +++++++++++++++++++---------------------
|
||||
1 file changed, 28 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c
|
||||
index ecf7f1ca161b..101260770ba7 100644
|
||||
--- a/libfreerdp/codec/clear.c
|
||||
+++ b/libfreerdp/codec/clear.c
|
||||
@@ -591,13 +591,9 @@ static BOOL resize_vbar_entry(CLEAR_CONTEXT* clear, CLEAR_VBAR_ENTRY* vBarEntry)
|
||||
static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 bandsByteCount,
|
||||
UINT32 nWidth, UINT32 nHeight, BYTE* pDstData,
|
||||
UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
||||
- UINT32 nYDst)
|
||||
+ UINT32 nYDst, UINT32 nDstWidth, UINT32 nDstHeight)
|
||||
{
|
||||
- UINT32 i, y;
|
||||
- UINT32 count;
|
||||
- UINT32 suboffset;
|
||||
- UINT32 nXDstRel;
|
||||
- UINT32 nYDstRel;
|
||||
+ UINT32 suboffset = 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < bandsByteCount)
|
||||
{
|
||||
@@ -605,22 +601,20 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- suboffset = 0;
|
||||
-
|
||||
while (suboffset < bandsByteCount)
|
||||
{
|
||||
- BYTE r, g, b;
|
||||
+ BYTE cr, cg, cb;
|
||||
UINT16 xStart;
|
||||
UINT16 xEnd;
|
||||
UINT16 yStart;
|
||||
UINT16 yEnd;
|
||||
UINT32 colorBkg;
|
||||
UINT16 vBarHeader;
|
||||
- UINT16 vBarYOn;
|
||||
+ UINT16 vBarYOn = 0;
|
||||
UINT16 vBarYOff;
|
||||
UINT32 vBarCount;
|
||||
UINT32 vBarPixelCount;
|
||||
- UINT32 vBarShortPixelCount;
|
||||
+ UINT32 vBarShortPixelCount = 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 11)
|
||||
{
|
||||
@@ -632,11 +626,11 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
Stream_Read_UINT16(s, xEnd);
|
||||
Stream_Read_UINT16(s, yStart);
|
||||
Stream_Read_UINT16(s, yEnd);
|
||||
- Stream_Read_UINT8(s, b);
|
||||
- Stream_Read_UINT8(s, g);
|
||||
- Stream_Read_UINT8(s, r);
|
||||
+ Stream_Read_UINT8(s, cb);
|
||||
+ Stream_Read_UINT8(s, cg);
|
||||
+ Stream_Read_UINT8(s, cr);
|
||||
suboffset += 11;
|
||||
- colorBkg = FreeRDPGetColor(clear->format, r, g, b, 0xFF);
|
||||
+ colorBkg = FreeRDPGetColor(clear->format, cr, cg, cb, 0xFF);
|
||||
|
||||
if (xEnd < xStart)
|
||||
{
|
||||
@@ -652,13 +646,13 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
|
||||
vBarCount = (xEnd - xStart) + 1;
|
||||
|
||||
- for (i = 0; i < vBarCount; i++)
|
||||
+ for (UINT32 i = 0; i < vBarCount; i++)
|
||||
{
|
||||
UINT32 vBarHeight;
|
||||
CLEAR_VBAR_ENTRY* vBarEntry = NULL;
|
||||
- CLEAR_VBAR_ENTRY* vBarShortEntry;
|
||||
+ CLEAR_VBAR_ENTRY* vBarShortEntry = NULL;
|
||||
BOOL vBarUpdate = FALSE;
|
||||
- const BYTE* pSrcPixel;
|
||||
+ const BYTE* cpSrcPixel;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
{
|
||||
@@ -740,11 +734,11 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
if (!resize_vbar_entry(clear, vBarShortEntry))
|
||||
return FALSE;
|
||||
|
||||
- for (y = 0; y < vBarShortPixelCount; y++)
|
||||
+ for (UINT32 y = 0; y < vBarShortPixelCount; y++)
|
||||
{
|
||||
- BYTE r, g, b;
|
||||
+ BYTE r = 0, g = 0, b = 0;
|
||||
BYTE* dstBuffer = &vBarShortEntry->pixels[y * GetBytesPerPixel(clear->format)];
|
||||
- UINT32 color;
|
||||
+ UINT32 color = 0;
|
||||
Stream_Read_UINT8(s, b);
|
||||
Stream_Read_UINT8(s, g);
|
||||
Stream_Read_UINT8(s, r);
|
||||
@@ -804,8 +798,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
|
||||
dstBuffer = vBarEntry->pixels;
|
||||
/* if (y < vBarYOn), use colorBkg */
|
||||
- y = 0;
|
||||
- count = vBarYOn;
|
||||
+ UINT32 y = 0;
|
||||
+ UINT32 count = vBarYOn;
|
||||
|
||||
if ((y + count) > vBarPixelCount)
|
||||
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
|
||||
@@ -868,28 +862,31 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- nXDstRel = nXDst + xStart;
|
||||
- nYDstRel = nYDst + yStart;
|
||||
- pSrcPixel = vBarEntry->pixels;
|
||||
+ const UINT32 nXDstRel = nXDst + xStart;
|
||||
+ const UINT32 nYDstRel = nYDst + yStart;
|
||||
+ cpSrcPixel = vBarEntry->pixels;
|
||||
|
||||
if (i < nWidth)
|
||||
{
|
||||
- count = vBarEntry->count;
|
||||
+ UINT32 count = vBarEntry->count;
|
||||
|
||||
if (count > nHeight)
|
||||
count = nHeight;
|
||||
|
||||
- for (y = 0; y < count; y++)
|
||||
+ if (nXDstRel + i > nDstWidth)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ for (UINT32 y = 0; y < count; y++)
|
||||
{
|
||||
BYTE* pDstPixel8 = &pDstData[((nYDstRel + y) * nDstStep) +
|
||||
((nXDstRel + i) * GetBytesPerPixel(DstFormat))];
|
||||
- UINT32 color = ReadColor(pSrcPixel, clear->format);
|
||||
+ UINT32 color = ReadColor(cpSrcPixel, clear->format);
|
||||
color = FreeRDPConvertColor(color, clear->format, DstFormat, NULL);
|
||||
|
||||
if (!WriteColor(pDstPixel8, DstFormat, color))
|
||||
return FALSE;
|
||||
|
||||
- pSrcPixel += GetBytesPerPixel(clear->format);
|
||||
+ cpSrcPixel += GetBytesPerPixel(clear->format);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1117,7 +1114,7 @@ INT32 clear_decompress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSiz
|
||||
if (bandsByteCount > 0)
|
||||
{
|
||||
if (!clear_decompress_bands_data(clear, s, bandsByteCount, nWidth, nHeight, pDstData,
|
||||
- DstFormat, nDstStep, nXDst, nYDst))
|
||||
+ DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight))
|
||||
{
|
||||
WLog_ERR(TAG, "clear_decompress_bands_data failed!");
|
||||
goto fail;
|
||||
33
debian/patches/0045-CVE-2023-40181.patch
vendored
Normal file
33
debian/patches/0045-CVE-2023-40181.patch
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
Description: Upstream fix for CVE-2023-40181 - Underflow leading to Out-Of-Bound Read in zgfx_decompress_segment
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/c23cbdc4a5756bd723223c7139654de7439fdcc0
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-mxp4-rx7x-h2g8
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From c23cbdc4a5756bd723223c7139654de7439fdcc0 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Mon, 21 Aug 2023 14:30:11 +0200
|
||||
Subject: [PATCH] [codec,zgfx] fix cBitsRemaining calculation
|
||||
|
||||
fixed out of bound read reported by @pwn2carr
|
||||
|
||||
(cherry picked from commit c39c82277a73332e9c1b64db98a34559f424fe20)
|
||||
---
|
||||
libfreerdp/codec/zgfx.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c
|
||||
index e260aa6e28ad..841b50860711 100644
|
||||
--- a/libfreerdp/codec/zgfx.c
|
||||
+++ b/libfreerdp/codec/zgfx.c
|
||||
@@ -259,7 +259,11 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||
zgfx->pbInputCurrent = pbSegment;
|
||||
zgfx->pbInputEnd = &pbSegment[cbSegment - 1];
|
||||
/* NumberOfBitsToDecode = ((NumberOfBytesToDecode - 1) * 8) - ValueOfLastByte */
|
||||
- zgfx->cBitsRemaining = 8 * (cbSegment - 1) - *zgfx->pbInputEnd;
|
||||
+ const UINT32 bits = 8u * (cbSegment - 1u);
|
||||
+ if (bits < *zgfx->pbInputEnd)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ zgfx->cBitsRemaining = bits - *zgfx->pbInputEnd;
|
||||
zgfx->cBitsCurrent = 0;
|
||||
zgfx->BitsCurrent = 0;
|
||||
|
||||
393
debian/patches/0046-CVE-2023-40186.patch
vendored
Normal file
393
debian/patches/0046-CVE-2023-40186.patch
vendored
Normal file
@ -0,0 +1,393 @@
|
||||
Description: Upstream fix for CVE-2023-40186 - IntegerOverflow leading to Out-Of-Bound Write Vulnerability in gdi_CreateSurface
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/d8a1ac342ae375644c70579c33b5cf38fb43b083
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-hcj4-3c3r-5j3v
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From d8a1ac342ae375644c70579c33b5cf38fb43b083 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Tue, 22 Aug 2023 09:41:28 +0200
|
||||
Subject: [PATCH] [warnings] fix integer multiplications
|
||||
|
||||
Ensure the integer width for size arguments is 64bit in a
|
||||
multiplication. Leading 64bit constant 1ull expands width, a trailing
|
||||
one is ignored.
|
||||
|
||||
(cherry picked from commit b3f0ab2814e39e0f779343c53699e7dc6c1b1c22)
|
||||
---
|
||||
channels/rdpsnd/server/rdpsnd_main.c | 2 +-
|
||||
client/X11/xf_gdi.c | 2 +-
|
||||
client/X11/xf_gfx.c | 4 ++--
|
||||
client/X11/xf_graphics.c | 4 ++--
|
||||
client/X11/xf_rail.c | 4 ++--
|
||||
libfreerdp/codec/clear.c | 4 ++--
|
||||
libfreerdp/codec/color.c | 6 +++---
|
||||
libfreerdp/codec/h264.c | 6 +++---
|
||||
libfreerdp/codec/progressive.c | 2 +-
|
||||
libfreerdp/gdi/bitmap.c | 2 +-
|
||||
libfreerdp/gdi/gdi.c | 2 +-
|
||||
libfreerdp/gdi/gfx.c | 4 ++--
|
||||
libfreerdp/gdi/graphics.c | 2 +-
|
||||
libfreerdp/gdi/shape.c | 2 +-
|
||||
libfreerdp/gdi/video.c | 2 +-
|
||||
libfreerdp/primitives/prim_copy.c | 4 ++--
|
||||
libfreerdp/primitives/primitives.c | 2 +-
|
||||
uwac/libuwac/uwac-window.c | 8 ++++----
|
||||
winpr/libwinpr/utils/lodepng/lodepng.c | 14 +++++++-------
|
||||
19 files changed, 38 insertions(+), 38 deletions(-)
|
||||
|
||||
--- a/channels/rdpsnd/server/rdpsnd_main.c
|
||||
+++ b/channels/rdpsnd/server/rdpsnd_main.c
|
||||
@@ -422,7 +422,7 @@
|
||||
Stream_Seek(s, 3); /* bPad */
|
||||
start = Stream_GetPosition(s);
|
||||
src = context->priv->out_buffer;
|
||||
- length = context->priv->out_pending_frames * context->priv->src_bytes_per_frame * 1ULL;
|
||||
+ length = 1ull * context->priv->out_pending_frames * context->priv->src_bytes_per_frame;
|
||||
|
||||
if (!freerdp_dsp_encode(context->priv->dsp_context, context->src_format, src, length, s))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
--- a/client/X11/xf_gdi.c
|
||||
+++ b/client/X11/xf_gdi.c
|
||||
@@ -1066,7 +1066,7 @@
|
||||
case RDP_CODEC_ID_NONE:
|
||||
pSrcData = cmd->bmp.bitmapData;
|
||||
format = gdi_get_pixel_format(cmd->bmp.bpp);
|
||||
- size = cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format) * 1ULL;
|
||||
+ size = 1ull * cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format);
|
||||
if (size > cmd->bmp.bitmapDataLength)
|
||||
{
|
||||
WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz,
|
||||
--- a/client/X11/xf_gfx.c
|
||||
+++ b/client/X11/xf_gfx.c
|
||||
@@ -288,7 +288,7 @@
|
||||
|
||||
surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel(surface->gdi.format);
|
||||
surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad);
|
||||
- size = surface->gdi.scanline * surface->gdi.height * 1ULL;
|
||||
+ size = 1ull * surface->gdi.scanline * surface->gdi.height;
|
||||
surface->gdi.data = (BYTE*)_aligned_malloc(size, 16);
|
||||
|
||||
if (!surface->gdi.data)
|
||||
@@ -312,7 +312,7 @@
|
||||
UINT32 bytes = GetBytesPerPixel(gdi->dstFormat);
|
||||
surface->stageScanline = width * bytes;
|
||||
surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad);
|
||||
- size = surface->stageScanline * surface->gdi.height * 1ULL;
|
||||
+ size = 1ull * surface->stageScanline * surface->gdi.height;
|
||||
surface->stage = (BYTE*)_aligned_malloc(size, 16);
|
||||
|
||||
if (!surface->stage)
|
||||
--- a/client/X11/xf_graphics.c
|
||||
+++ b/client/X11/xf_graphics.c
|
||||
@@ -304,7 +304,7 @@
|
||||
ci.height = yTargetSize;
|
||||
ci.xhot = pointer->xPos * xscale;
|
||||
ci.yhot = pointer->yPos * yscale;
|
||||
- size = ci.height * ci.width * GetBytesPerPixel(CursorFormat) * 1ULL;
|
||||
+ size = 1ull * ci.height * ci.width * GetBytesPerPixel(CursorFormat);
|
||||
|
||||
if (xscale != 1 || yscale != 1)
|
||||
{
|
||||
@@ -391,7 +391,7 @@
|
||||
xpointer->nCursors = 0;
|
||||
xpointer->mCursors = 0;
|
||||
|
||||
- size = pointer->height * pointer->width * GetBytesPerPixel(CursorFormat) * 1ULL;
|
||||
+ size = 1ull * pointer->height * pointer->width * GetBytesPerPixel(CursorFormat);
|
||||
|
||||
if (!(xpointer->cursorPixels = (XcursorPixel*)_aligned_malloc(size, 16)))
|
||||
return FALSE;
|
||||
--- a/client/X11/xf_rail.c
|
||||
+++ b/client/X11/xf_rail.c
|
||||
@@ -532,7 +532,7 @@
|
||||
|
||||
cache->numCaches = settings->RemoteAppNumIconCaches;
|
||||
cache->numCacheEntries = settings->RemoteAppNumIconCacheEntries;
|
||||
- cache->entries = calloc(cache->numCaches * cache->numCacheEntries * 1ULL, sizeof(xfRailIcon));
|
||||
+ cache->entries = calloc(1ull * cache->numCaches * cache->numCacheEntries, sizeof(xfRailIcon));
|
||||
|
||||
if (!cache->entries)
|
||||
{
|
||||
@@ -602,7 +602,7 @@
|
||||
long* pixels;
|
||||
int i;
|
||||
int nelements;
|
||||
- argbPixels = calloc(iconInfo->width * iconInfo->height * 1ULL, 4);
|
||||
+ argbPixels = calloc(1ull * iconInfo->width * iconInfo->height, 4);
|
||||
|
||||
if (!argbPixels)
|
||||
goto error;
|
||||
--- a/libfreerdp/codec/clear.c
|
||||
+++ b/libfreerdp/codec/clear.c
|
||||
@@ -566,7 +566,7 @@
|
||||
const UINT32 diffSize = (vBarEntry->count - vBarEntry->size) * bpp;
|
||||
BYTE* tmp;
|
||||
vBarEntry->size = vBarEntry->count;
|
||||
- tmp = (BYTE*)realloc(vBarEntry->pixels, vBarEntry->count * bpp * 1ULL);
|
||||
+ tmp = (BYTE*)realloc(vBarEntry->pixels, 1ull * vBarEntry->count * bpp);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
@@ -977,7 +977,7 @@
|
||||
if (glyphEntry->count > glyphEntry->size)
|
||||
{
|
||||
BYTE* tmp;
|
||||
- tmp = realloc(glyphEntry->pixels, glyphEntry->count * bpp * 1ULL);
|
||||
+ tmp = realloc(glyphEntry->pixels, 1ull * glyphEntry->count * bpp);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
--- a/libfreerdp/codec/color.c
|
||||
+++ b/libfreerdp/codec/color.c
|
||||
@@ -56,7 +56,7 @@
|
||||
* means of accessing individual pixels in blitting operations
|
||||
*/
|
||||
scanline = (width + 7) / 8;
|
||||
- dstData = (BYTE*)_aligned_malloc(width * height * 1ULL, 16);
|
||||
+ dstData = (BYTE*)_aligned_malloc(1ull * width * height, 16);
|
||||
|
||||
if (!dstData)
|
||||
return NULL;
|
||||
@@ -545,7 +545,7 @@
|
||||
for (y = nYDst; y < nHeight; y++)
|
||||
{
|
||||
BYTE* pDstLine = &pDstData[y * nDstStep + nXDst * dstBytesPerPixel];
|
||||
- memset(pDstLine, 0, dstBytesPerPixel * (nWidth - nXDst) * 1ULL);
|
||||
+ memset(pDstLine, 0, 1ull * dstBytesPerPixel * (nWidth - nXDst));
|
||||
}
|
||||
|
||||
switch (xorBpp)
|
||||
@@ -742,7 +742,7 @@
|
||||
for (y = 1; y < nHeight; y++)
|
||||
{
|
||||
BYTE* pDstLine = &pDstData[(y + nYDst) * nDstStep + nXDst * bpp];
|
||||
- memcpy(pDstLine, pFirstDstLineXOffset, nWidth * bpp * 1ULL);
|
||||
+ memcpy(pDstLine, pFirstDstLineXOffset, 1ull * nWidth * bpp);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
--- a/libfreerdp/codec/h264.c
|
||||
+++ b/libfreerdp/codec/h264.c
|
||||
@@ -63,9 +63,9 @@
|
||||
_aligned_free(h264->pYUVData[0]);
|
||||
_aligned_free(h264->pYUVData[1]);
|
||||
_aligned_free(h264->pYUVData[2]);
|
||||
- h264->pYUVData[0] = _aligned_malloc(h264->iStride[0] * height * 1ULL, 16);
|
||||
- h264->pYUVData[1] = _aligned_malloc(h264->iStride[1] * height * 1ULL, 16);
|
||||
- h264->pYUVData[2] = _aligned_malloc(h264->iStride[2] * height * 1ULL, 16);
|
||||
+ h264->pYUVData[0] = _aligned_malloc(1ull * h264->iStride[0] * height, 16);
|
||||
+ h264->pYUVData[1] = _aligned_malloc(1ull * h264->iStride[1] * height, 16);
|
||||
+ h264->pYUVData[2] = _aligned_malloc(1ull * h264->iStride[2] * height, 16);
|
||||
|
||||
if (!h264->pYUVData[0] || !h264->pYUVData[1] || !h264->pYUVData[2])
|
||||
return FALSE;
|
||||
--- a/libfreerdp/codec/progressive.c
|
||||
+++ b/libfreerdp/codec/progressive.c
|
||||
@@ -411,7 +411,7 @@
|
||||
tile->stride = 4 * tile->width;
|
||||
|
||||
{
|
||||
- size_t dataLen = tile->stride * tile->height * 1ULL;
|
||||
+ size_t dataLen = 1ull * tile->stride * tile->height;
|
||||
tile->data = (BYTE*)_aligned_malloc(dataLen, 16);
|
||||
}
|
||||
|
||||
--- a/libfreerdp/gdi/bitmap.c
|
||||
+++ b/libfreerdp/gdi/bitmap.c
|
||||
@@ -148,7 +148,7 @@
|
||||
hBitmap->width = nWidth;
|
||||
hBitmap->height = nHeight;
|
||||
hBitmap->data =
|
||||
- _aligned_malloc(nWidth * nHeight * GetBytesPerPixel(hBitmap->format) * 1ULL, 16);
|
||||
+ _aligned_malloc(1ull * nWidth * nHeight * GetBytesPerPixel(hBitmap->format), 16);
|
||||
hBitmap->free = _aligned_free;
|
||||
|
||||
if (!hBitmap->data)
|
||||
--- a/libfreerdp/gdi/gdi.c
|
||||
+++ b/libfreerdp/gdi/gdi.c
|
||||
@@ -1057,7 +1057,7 @@
|
||||
|
||||
case RDP_CODEC_ID_NONE:
|
||||
format = gdi_get_pixel_format(cmd->bmp.bpp);
|
||||
- size = cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format) * 1ULL;
|
||||
+ size = 1ull * cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format);
|
||||
if (size > cmd->bmp.bitmapDataLength)
|
||||
{
|
||||
WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz,
|
||||
--- a/libfreerdp/gdi/gfx.c
|
||||
+++ b/libfreerdp/gdi/gfx.c
|
||||
@@ -730,7 +730,7 @@
|
||||
{
|
||||
UINT32 x, y;
|
||||
|
||||
- if (Stream_GetRemainingLength(&s) < cmd->height * cmd->width * 1ULL)
|
||||
+ if (Stream_GetRemainingLength(&s) < 1ull * cmd->height * cmd->width)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
for (y = cmd->top; y < cmd->top + cmd->height; y++)
|
||||
@@ -1029,7 +1029,7 @@
|
||||
}
|
||||
|
||||
surface->scanline = gfx_align_scanline(surface->width * 4UL, 16);
|
||||
- surface->data = (BYTE*)_aligned_malloc(surface->scanline * surface->height * 1ULL, 16);
|
||||
+ surface->data = (BYTE*)_aligned_malloc(1ull * surface->scanline * surface->height, 16);
|
||||
|
||||
if (!surface->data)
|
||||
{
|
||||
--- a/libfreerdp/gdi/graphics.c
|
||||
+++ b/libfreerdp/gdi/graphics.c
|
||||
@@ -52,7 +52,7 @@
|
||||
return NULL;
|
||||
|
||||
nDstStep = nWidth * GetBytesPerPixel(gdi->dstFormat);
|
||||
- pDstData = _aligned_malloc(nHeight * nDstStep * 1ULL, 16);
|
||||
+ pDstData = _aligned_malloc(1ull * nHeight * nDstStep, 16);
|
||||
|
||||
if (!pDstData)
|
||||
return NULL;
|
||||
--- a/libfreerdp/gdi/shape.c
|
||||
+++ b/libfreerdp/gdi/shape.c
|
||||
@@ -158,7 +158,7 @@
|
||||
for (y = 1; y < nHeight; y++)
|
||||
{
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
|
||||
- memcpy(dstp, srcp, nWidth * formatSize * 1ULL);
|
||||
+ memcpy(dstp, srcp, 1ull * nWidth * formatSize);
|
||||
}
|
||||
|
||||
break;
|
||||
--- a/libfreerdp/gdi/video.c
|
||||
+++ b/libfreerdp/gdi/video.c
|
||||
@@ -66,7 +66,7 @@
|
||||
ret->base.w = width;
|
||||
ret->base.h = height;
|
||||
ret->scanline = width * bpp;
|
||||
- ret->image = _aligned_malloc(ret->scanline * height * 1ULL, 16);
|
||||
+ ret->image = _aligned_malloc(1ull * ret->scanline * height, 16);
|
||||
|
||||
if (!ret->image)
|
||||
{
|
||||
--- a/libfreerdp/primitives/prim_copy.c
|
||||
+++ b/libfreerdp/primitives/prim_copy.c
|
||||
@@ -60,14 +60,14 @@
|
||||
|
||||
if (p1m <= p2m)
|
||||
{
|
||||
- ULONG_PTR p1mEnd = p1m + (height - 1) * p1Step * 1ULL + width * p1Size * 1ULL;
|
||||
+ ULONG_PTR p1mEnd = p1m + 1ull * (height - 1) * p1Step + 1ull * width * p1Size;
|
||||
|
||||
if (p1mEnd > p2m)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
- ULONG_PTR p2mEnd = p2m + (height - 1) * p2Step * 1ULL + width * p2Size * 1ULL;
|
||||
+ ULONG_PTR p2mEnd = p2m + 1ull * (height - 1) * p2Step + 1ull * width * p2Size;
|
||||
|
||||
if (p2mEnd > p1m)
|
||||
return TRUE;
|
||||
--- a/libfreerdp/primitives/primitives.c
|
||||
+++ b/libfreerdp/primitives/primitives.c
|
||||
@@ -157,7 +157,7 @@
|
||||
if (!buf)
|
||||
goto fail;
|
||||
|
||||
- winpr_RAND(buf, roi->width * roi->height * 1ULL);
|
||||
+ winpr_RAND(buf, 1ull * roi->width * roi->height);
|
||||
ret->steps[i] = roi->width;
|
||||
}
|
||||
|
||||
--- a/uwac/libuwac/uwac-window.c
|
||||
+++ b/uwac/libuwac/uwac-window.c
|
||||
@@ -316,14 +316,14 @@
|
||||
|
||||
w->buffers = newBuffers;
|
||||
memset(w->buffers + w->nbuffers, 0, sizeof(UwacBuffer) * nbuffers);
|
||||
- fd = uwac_create_anonymous_file(allocSize * nbuffers * 1ULL);
|
||||
+ fd = uwac_create_anonymous_file(1ull * allocSize * nbuffers);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
- data = mmap(NULL, allocSize * nbuffers * 1ULL, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
+ data = mmap(NULL, 1ull * allocSize * nbuffers, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
if (data == MAP_FAILED)
|
||||
{
|
||||
@@ -335,7 +335,7 @@
|
||||
|
||||
if (!pool)
|
||||
{
|
||||
- munmap(data, allocSize * nbuffers * 1ULL);
|
||||
+ munmap(data, 1ull * allocSize * nbuffers);
|
||||
ret = UWAC_ERROR_NOMEMORY;
|
||||
goto error_mmap;
|
||||
}
|
||||
@@ -756,7 +756,7 @@
|
||||
|
||||
if (copyContentForNextFrame)
|
||||
memcpy(nextDrawingBuffer->data, pendingBuffer->data,
|
||||
- window->stride * window->height * 1ULL);
|
||||
+ 1ull * window->stride * window->height);
|
||||
|
||||
UwacSubmitBufferPtr(window, pendingBuffer);
|
||||
return UWAC_SUCCESS;
|
||||
--- a/winpr/libwinpr/utils/lodepng/lodepng.c
|
||||
+++ b/winpr/libwinpr/utils/lodepng/lodepng.c
|
||||
@@ -3814,7 +3814,7 @@
|
||||
{
|
||||
size_t i;
|
||||
ColorTree tree;
|
||||
- size_t numpixels = w * h * 1ULL;
|
||||
+ size_t numpixels = 1ull * w * h;
|
||||
|
||||
if (lodepng_color_mode_equal(mode_out, mode_in))
|
||||
{
|
||||
@@ -3917,7 +3917,7 @@
|
||||
unsigned error = 0;
|
||||
size_t i;
|
||||
ColorTree tree;
|
||||
- size_t numpixels = w * h * 1ULL;
|
||||
+ size_t numpixels = 1ull * w * h;
|
||||
|
||||
unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0;
|
||||
unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1;
|
||||
@@ -4538,7 +4538,7 @@
|
||||
if (bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
|
||||
{
|
||||
CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp));
|
||||
- removePaddingBits(out, in, w * bpp * 1ULL, ((w * bpp + 7ULL) / 8ULL) * 8ULL, h);
|
||||
+ removePaddingBits(out, in, 1ull * w * bpp, ((w * bpp + 7ULL) / 8ULL) * 8ULL, h);
|
||||
}
|
||||
/*we can immediatly filter into the out buffer, no other steps needed*/
|
||||
else
|
||||
@@ -4564,7 +4564,7 @@
|
||||
bits between the different reduced images: each reduced image still starts nicely at
|
||||
a byte*/
|
||||
removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]],
|
||||
- passw[i] * bpp * 1ULL, ((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL,
|
||||
+ 1ull * passw[i] * bpp, ((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL,
|
||||
passh[i]);
|
||||
}
|
||||
}
|
||||
@@ -6055,7 +6055,7 @@
|
||||
error = 83; /*alloc fail*/
|
||||
if (!error)
|
||||
{
|
||||
- addPaddingBits(padded, in, ((w * bpp + 7ULL) / 8ULL) * 8ULL, w * bpp * 1ULL, h);
|
||||
+ addPaddingBits(padded, in, ((w * bpp + 7ULL) / 8ULL) * 8ULL, 1ull * w * bpp, h);
|
||||
error = filter(*out, padded, w, h, &info_png->color, settings);
|
||||
}
|
||||
free(padded);
|
||||
@@ -6099,8 +6099,8 @@
|
||||
if (!padded)
|
||||
ERROR_BREAK(83); /*alloc fail*/
|
||||
addPaddingBits(padded, &adam7[passstart[i]],
|
||||
- ((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL, passw[i] * bpp * 1ULL,
|
||||
- passh[i] * 1ULL);
|
||||
+ ((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL, 1ull * passw[i] * bpp,
|
||||
+ 1ull * passh[i]);
|
||||
error = filter(&(*out)[filter_passstart[i]], padded, passw[i], passh[i],
|
||||
&info_png->color, settings);
|
||||
free(padded);
|
||||
36
debian/patches/0047-CVE-2023-40188.patch
vendored
Normal file
36
debian/patches/0047-CVE-2023-40188.patch
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
Description: Upstream fix for CVE-2023-40188 - Out-Of-Bounds Read in general_LumaToYUV444
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/bdb3909a7713fb0b3d94c9676fe44d19de80eb4b
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-9w28-wwj5-p4xq
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From bdb3909a7713fb0b3d94c9676fe44d19de80eb4b Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Tue, 22 Aug 2023 10:06:15 +0200
|
||||
Subject: [PATCH] [codec,nsc] ensure integer width
|
||||
|
||||
ensure multiplication result is 64bit
|
||||
|
||||
(cherry picked from commit adb1630d623f76b314631e338559afe4d62b24fa)
|
||||
---
|
||||
libfreerdp/codec/nsc.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/libfreerdp/codec/nsc.c
|
||||
+++ b/libfreerdp/codec/nsc.c
|
||||
@@ -274,7 +274,7 @@
|
||||
if (!nsc_stream_initialize(context, s))
|
||||
return FALSE;
|
||||
|
||||
- const size_t blength = context->width * context->height * 4;
|
||||
+ const size_t blength = context->width * context->height * 4ull;
|
||||
|
||||
if (!context->BitmapData)
|
||||
{
|
||||
@@ -300,7 +300,7 @@
|
||||
const UINT32 tempWidth = ROUND_UP_TO(context->width, 8);
|
||||
const UINT32 tempHeight = ROUND_UP_TO(context->height, 2);
|
||||
/* The maximum length a decoded plane can reach in all cases */
|
||||
- const size_t plength = tempWidth * tempHeight;
|
||||
+ const size_t plength = 1ull * tempWidth * tempHeight;
|
||||
|
||||
if (plength > context->priv->PlaneBuffersLength)
|
||||
{
|
||||
36
debian/patches/0048-CVE-2023-40569.patch
vendored
Normal file
36
debian/patches/0048-CVE-2023-40569.patch
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
Description: Upstream fix for CVE-2023-40569 - Out-Of-Bounds Write in progressive_decompress
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/23c3daeca1598393f8c93f563f7847a4d67919f1
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-hm8c-rcjg-c8qp
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From 23c3daeca1598393f8c93f563f7847a4d67919f1 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Tue, 22 Aug 2023 15:05:20 +0200
|
||||
Subject: [PATCH] [codec,progressive] fix missing destination checks
|
||||
|
||||
(cherry picked from commit ef7e0d60c207dae478952d795e74751d1516629d)
|
||||
---
|
||||
libfreerdp/codec/progressive.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/libfreerdp/codec/progressive.c
|
||||
+++ b/libfreerdp/codec/progressive.c
|
||||
@@ -2315,11 +2315,17 @@
|
||||
for (j = 0; j < nbUpdateRects; j++)
|
||||
{
|
||||
const RECTANGLE_16* rect = &updateRects[j];
|
||||
- const UINT32 nXSrc = rect->left - (nXDst + tile->x);
|
||||
- const UINT32 nYSrc = rect->top - (nYDst + tile->y);
|
||||
+ if (rect->left < updateRect.left)
|
||||
+ goto fail;
|
||||
+ const UINT32 nXSrc = rect->left - updateRect.left;
|
||||
+ const UINT32 nYSrc = rect->top - updateRect.top;
|
||||
const UINT32 width = rect->right - rect->left;
|
||||
const UINT32 height = rect->bottom - rect->top;
|
||||
|
||||
+ if (rect->left + width > surface->width)
|
||||
+ goto fail;
|
||||
+ if (rect->top + height > surface->height)
|
||||
+ goto fail;
|
||||
if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width,
|
||||
height, tile->data, progressive->format, tile->stride, nXSrc,
|
||||
nYSrc, NULL, FREERDP_FLIP_NONE))
|
||||
319
debian/patches/0049-CVE-2023-40589.patch
vendored
Normal file
319
debian/patches/0049-CVE-2023-40589.patch
vendored
Normal file
@ -0,0 +1,319 @@
|
||||
Description: Upstream fix for CVE-2023-40569 - Global-Buffer-Overflow in ncrush_decompress
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/c659973bb4cd65c065f2fe1a807dbc6805c684c6
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-gc34-mw6m-g42x
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1051638
|
||||
From c659973bb4cd65c065f2fe1a807dbc6805c684c6 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Mon, 28 Aug 2023 09:06:42 +0200
|
||||
Subject: [PATCH] [codec,ncrush] fix index checks
|
||||
|
||||
properly verify all offsets while decoding data.
|
||||
|
||||
(cherry picked from commit 880285c332a1d98334fd8fa4b06c10fba0fb6959)
|
||||
---
|
||||
libfreerdp/codec/ncrush.c | 137 ++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 108 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/codec/ncrush.c b/libfreerdp/codec/ncrush.c
|
||||
index 3d6a216d32f4..c1d622a9c0bd 100644
|
||||
--- a/libfreerdp/codec/ncrush.c
|
||||
+++ b/libfreerdp/codec/ncrush.c
|
||||
@@ -1994,15 +1994,9 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
UINT32* pDstSize, UINT32 flags)
|
||||
{
|
||||
UINT32 index;
|
||||
- UINT32 bits;
|
||||
- INT32 nbits;
|
||||
- const BYTE* SrcPtr;
|
||||
- const BYTE* SrcEnd;
|
||||
- UINT16 Mask;
|
||||
BYTE Literal;
|
||||
UINT32 IndexLEC;
|
||||
UINT32 BitLength;
|
||||
- UINT32 MaskedBits;
|
||||
UINT32 CopyOffset;
|
||||
UINT32 CopyLength;
|
||||
UINT32 OldCopyOffset;
|
||||
@@ -2010,9 +2004,6 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
UINT32 LengthOfMatch;
|
||||
UINT32 CopyOffsetIndex;
|
||||
UINT32 OffsetCacheIndex;
|
||||
- BYTE* HistoryPtr;
|
||||
- BYTE* HistoryBuffer;
|
||||
- BYTE* HistoryBufferEnd;
|
||||
UINT32 CopyOffsetBits;
|
||||
UINT32 CopyOffsetBase;
|
||||
UINT32 LengthOfMatchBits;
|
||||
@@ -2021,8 +2012,8 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
if (ncrush->HistoryEndOffset != 65535)
|
||||
return -1001;
|
||||
|
||||
- HistoryBuffer = ncrush->HistoryBuffer;
|
||||
- HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
|
||||
+ BYTE* HistoryBuffer = ncrush->HistoryBuffer;
|
||||
+ const BYTE* HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
|
||||
|
||||
if (flags & PACKET_AT_FRONT)
|
||||
{
|
||||
@@ -2041,7 +2032,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
|
||||
}
|
||||
|
||||
- HistoryPtr = ncrush->HistoryPtr;
|
||||
+ BYTE* HistoryPtr = ncrush->HistoryPtr;
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
{
|
||||
@@ -2050,17 +2041,19 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
return 1;
|
||||
}
|
||||
|
||||
- SrcEnd = &pSrcData[SrcSize];
|
||||
- nbits = 32;
|
||||
- bits = get_dword(pSrcData);
|
||||
- SrcPtr = pSrcData + 4;
|
||||
+ const BYTE* SrcEnd = &pSrcData[SrcSize];
|
||||
+ const BYTE* SrcPtr = pSrcData + 4;
|
||||
|
||||
+ INT32 nbits = 32;
|
||||
+ UINT32 bits = get_dword(pSrcData);
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
- Mask = get_word(&HuffTableMask[29]);
|
||||
- MaskedBits = bits & Mask;
|
||||
+ const UINT16 Mask = get_word(&HuffTableMask[29]);
|
||||
+ const UINT32 MaskedBits = bits & Mask;
|
||||
+ if (MaskedBits >= ARRAYSIZE(HuffTableLEC))
|
||||
+ return -1;
|
||||
IndexLEC = HuffTableLEC[MaskedBits] & 0xFFF;
|
||||
BitLength = HuffTableLEC[MaskedBits] >> 12;
|
||||
bits >>= BitLength;
|
||||
@@ -2096,8 +2089,10 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
return -1004;
|
||||
|
||||
CopyOffset = ncrush->OffsetCache[OffsetCacheIndex];
|
||||
- Mask = get_word(&HuffTableMask[21]);
|
||||
- MaskedBits = bits & Mask;
|
||||
+ const UINT16 Mask = get_word(&HuffTableMask[21]);
|
||||
+ const UINT32 MaskedBits = bits & Mask;
|
||||
+ if (MaskedBits > ARRAYSIZE(HuffTableLOM))
|
||||
+ return -1;
|
||||
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
||||
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
||||
bits >>= BitLength;
|
||||
@@ -2106,13 +2101,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
||||
return -1;
|
||||
|
||||
+ if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
|
||||
+ return -1;
|
||||
+
|
||||
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
||||
+
|
||||
+ if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
|
||||
+ return -1;
|
||||
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
||||
|
||||
if (LengthOfMatchBits)
|
||||
{
|
||||
- Mask = get_word(&HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
||||
- MaskedBits = bits & Mask;
|
||||
+ const size_t idx = (2ull * LengthOfMatchBits) + 3ull;
|
||||
+ if (idx >= ARRAYSIZE(HuffTableMask))
|
||||
+ return -1;
|
||||
+
|
||||
+ const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||
+ const UINT32 MaskedBits = bits & Mask;
|
||||
bits >>= LengthOfMatchBits;
|
||||
nbits -= LengthOfMatchBits;
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
@@ -2127,15 +2132,28 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
}
|
||||
else
|
||||
{
|
||||
+ if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBitsLUT))
|
||||
+ return -1;
|
||||
+
|
||||
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
||||
+
|
||||
+ if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBaseLUT))
|
||||
+ return -1;
|
||||
CopyOffsetBase = CopyOffsetBaseLUT[CopyOffsetIndex];
|
||||
CopyOffset = CopyOffsetBase - 1;
|
||||
|
||||
if (CopyOffsetBits)
|
||||
{
|
||||
- Mask = get_word(&HuffTableMask[(2 * CopyOffsetBits) + 3]);
|
||||
- MaskedBits = bits & Mask;
|
||||
- CopyOffset = CopyOffsetBase + MaskedBits - 1;
|
||||
+ const size_t idx = (2ull * CopyOffsetBits) + 3ull;
|
||||
+ if (idx >= ARRAYSIZE(HuffTableMask))
|
||||
+ return -1;
|
||||
+
|
||||
+ const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||
+ const UINT32 MaskedBits = bits & Mask;
|
||||
+ const UINT32 tmp = CopyOffsetBase + MaskedBits;
|
||||
+ if (tmp < 1)
|
||||
+ return -1;
|
||||
+ CopyOffset = tmp - 1;
|
||||
bits >>= CopyOffsetBits;
|
||||
nbits -= CopyOffsetBits;
|
||||
|
||||
@@ -2143,8 +2161,11 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
return -1;
|
||||
}
|
||||
|
||||
- Mask = get_word(&HuffTableMask[21]);
|
||||
- MaskedBits = bits & Mask;
|
||||
+ const UINT16 Mask = get_word(&HuffTableMask[21]);
|
||||
+ const UINT32 MaskedBits = bits & Mask;
|
||||
+ if (MaskedBits >= ARRAYSIZE(HuffTableLOM))
|
||||
+ return -1;
|
||||
+
|
||||
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
||||
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
||||
bits >>= BitLength;
|
||||
@@ -2153,13 +2174,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
||||
return -1;
|
||||
|
||||
+ if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
|
||||
+ return -1;
|
||||
+
|
||||
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
||||
+
|
||||
+ if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
|
||||
+ return -1;
|
||||
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
||||
|
||||
if (LengthOfMatchBits)
|
||||
{
|
||||
- Mask = get_word(&HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
||||
- MaskedBits = bits & Mask;
|
||||
+ const size_t idx = (2ull * LengthOfMatchBits) + 3ull;
|
||||
+ if (idx >= ARRAYSIZE(HuffTableMask))
|
||||
+ return -1;
|
||||
+
|
||||
+ const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||
+ const UINT32 MaskedBits = bits & Mask;
|
||||
bits >>= LengthOfMatchBits;
|
||||
nbits -= LengthOfMatchBits;
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
@@ -2583,7 +2614,12 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
}
|
||||
|
||||
IndexLEC = Literal;
|
||||
+ if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
+ return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
+
|
||||
+ if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
+ return -1;
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
if (BitLength > 15)
|
||||
@@ -2666,9 +2702,18 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
bits = CopyOffset;
|
||||
|
||||
CopyOffsetIndex = ncrush->HuffTableCopyOffset[bits + 2];
|
||||
+
|
||||
+ if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBitsLUT))
|
||||
+ return -1;
|
||||
+
|
||||
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
||||
IndexLEC = 257 + CopyOffsetIndex;
|
||||
+ if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
+ return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
+
|
||||
+ if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
+ return -1;
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
if (BitLength > 15)
|
||||
@@ -2687,13 +2732,23 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
else
|
||||
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
||||
|
||||
+ if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
|
||||
+ return -1;
|
||||
BitLength = HuffLengthLOM[IndexCO];
|
||||
+
|
||||
+ if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
|
||||
+ return -1;
|
||||
IndexLOM = LOMBitsLUT[IndexCO];
|
||||
+
|
||||
+ if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
|
||||
+ return -1;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
||||
Mask = ((1 << IndexLOM) - 1);
|
||||
MaskedBits = (MatchLength - 2) & Mask;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
||||
|
||||
+ if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
|
||||
+ return -1;
|
||||
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
||||
return -1010;
|
||||
}
|
||||
@@ -2701,7 +2756,11 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
{
|
||||
/* CopyOffset in OffsetCache */
|
||||
IndexLEC = 289 + OffsetCacheIndex;
|
||||
+ if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
+ return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
+ if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
+ return -1;
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
if (BitLength >= 15)
|
||||
@@ -2714,13 +2773,24 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
else
|
||||
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
||||
|
||||
+ if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
|
||||
+ return -1;
|
||||
+
|
||||
BitLength = HuffLengthLOM[IndexCO];
|
||||
+
|
||||
+ if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
|
||||
+ return -1;
|
||||
IndexLOM = LOMBitsLUT[IndexCO];
|
||||
+
|
||||
+ if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
|
||||
+ return -1;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
||||
Mask = ((1 << IndexLOM) - 1);
|
||||
MaskedBits = (MatchLength - 2) & Mask;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
||||
|
||||
+ if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
|
||||
+ return -1;
|
||||
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
||||
return -1012;
|
||||
}
|
||||
@@ -2745,6 +2815,10 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
Literal = *SrcPtr++;
|
||||
HistoryPtr++;
|
||||
IndexLEC = Literal;
|
||||
+ if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
+ return -1;
|
||||
+ if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
+ return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
@@ -2817,6 +2891,11 @@ static int ncrush_generate_tables(NCRUSH_CONTEXT* context)
|
||||
else
|
||||
i = context->HuffTableLOM[k];
|
||||
|
||||
+ if (i >= ARRAYSIZE(LOMBitsLUT))
|
||||
+ return -1;
|
||||
+ if (i >= ARRAYSIZE(LOMBaseLUT))
|
||||
+ return -1;
|
||||
+
|
||||
if (((((1 << LOMBitsLUT[i]) - 1) & (k - 2)) + LOMBaseLUT[i]) != k)
|
||||
return -1;
|
||||
}
|
||||
153
debian/patches/0050-CVE-2021-41160.patch
vendored
Normal file
153
debian/patches/0050-CVE-2021-41160.patch
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
Description: Fix for CVE-2021-41160 - out of bound write
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/217e0caa181fc1690cf84dd6a3ba1a4f90c02692.
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-7c9r-6r2q-93qg
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1001062
|
||||
|
||||
From 217e0caa181fc1690cf84dd6a3ba1a4f90c02692 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@users.noreply.github.com>
|
||||
Date: Tue, 12 Oct 2021 12:26:22 +0200
|
||||
Subject: [PATCH] Bitmap update fix (#7349)
|
||||
|
||||
* Added checks for bitmap width and height values
|
||||
|
||||
Data received from the server might have invalid values for bitmap
|
||||
with or height. Abort parsing if such a value is found.
|
||||
Reported by Sunglin from the Knownsec 404 team & 0103 sec team
|
||||
|
||||
* Added checks for glyph width & height
|
||||
---
|
||||
libfreerdp/core/orders.c | 14 ++++++++++++
|
||||
libfreerdp/core/surface.c | 45 +++++++++++++++++++++++++++++++++++++++
|
||||
libfreerdp/core/update.c | 7 ++++++
|
||||
3 files changed, 66 insertions(+)
|
||||
|
||||
--- a/libfreerdp/core/orders.c
|
||||
+++ b/libfreerdp/core/orders.c
|
||||
@@ -1948,6 +1948,13 @@
|
||||
!update_read_2byte_unsigned(&sub, &glyph->cy))
|
||||
return FALSE;
|
||||
|
||||
+ if ((glyph->cx == 0) || (glyph->cy == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "GLYPH_DATA_V2::cx=%" PRIu32 ", GLYPH_DATA_V2::cy=%" PRIu32,
|
||||
+ glyph->cx, glyph->cy);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
glyph->cb = Stream_GetRemainingLength(&sub);
|
||||
if (glyph->cb > 0)
|
||||
{
|
||||
@@ -2949,6 +2956,13 @@
|
||||
Stream_Read_UINT16(s, create_offscreen_bitmap->cy); /* cy (2 bytes) */
|
||||
deleteList = &(create_offscreen_bitmap->deleteList);
|
||||
|
||||
+ if ((create_offscreen_bitmap->cx == 0) || (create_offscreen_bitmap->cy == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "Invalid OFFSCREEN_DELETE_LIST: cx=%" PRIu16 ", cy=%" PRIu16,
|
||||
+ create_offscreen_bitmap->cx, create_offscreen_bitmap->cy);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if (deleteListPresent)
|
||||
{
|
||||
UINT32 i;
|
||||
--- a/libfreerdp/core/surface.c
|
||||
+++ b/libfreerdp/core/surface.c
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
+#include <assert.h>
|
||||
+
|
||||
#include <freerdp/utils/pcap.h>
|
||||
#include <freerdp/log.h>
|
||||
|
||||
@@ -29,6 +31,8 @@
|
||||
|
||||
#define TAG FREERDP_TAG("core.surface")
|
||||
|
||||
+#define WINPR_ASSERT assert
|
||||
+
|
||||
static BOOL update_recv_surfcmd_bitmap_header_ex(wStream* s, TS_COMPRESSED_BITMAP_HEADER_EX* header)
|
||||
{
|
||||
if (!s || !header)
|
||||
@@ -62,6 +66,13 @@
|
||||
Stream_Read_UINT16(s, bmp->height);
|
||||
Stream_Read_UINT32(s, bmp->bitmapDataLength);
|
||||
|
||||
+ if ((bmp->width == 0) || (bmp->height == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "invalid size value width=%" PRIu16 ", height=%" PRIu16, bmp->width,
|
||||
+ bmp->height);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if ((bmp->bpp < 1) || (bmp->bpp > 32))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid bpp value %" PRIu32 "", bmp->bpp);
|
||||
@@ -85,6 +96,39 @@
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static BOOL update_recv_surfcmd_is_rect_valid(const rdpContext* context,
|
||||
+ const SURFACE_BITS_COMMAND* cmd)
|
||||
+{
|
||||
+ WINPR_ASSERT(context);
|
||||
+ WINPR_ASSERT(context->settings);
|
||||
+ WINPR_ASSERT(cmd);
|
||||
+
|
||||
+ /* We need a rectangle with left/top being smaller than right/bottom.
|
||||
+ * Also do not allow empty rectangles. */
|
||||
+ if ((cmd->destTop >= cmd->destBottom) || (cmd->destLeft >= cmd->destRight))
|
||||
+ {
|
||||
+ WLog_WARN(TAG,
|
||||
+ "Empty surface bits command rectangle: %" PRIu16 "x%" PRIu16 "-%" PRIu16
|
||||
+ "x%" PRIu16,
|
||||
+ cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* The rectangle needs to fit into our session size */
|
||||
+ if ((cmd->destRight > context->settings->DesktopWidth) ||
|
||||
+ (cmd->destBottom > context->settings->DesktopHeight))
|
||||
+ {
|
||||
+ WLog_WARN(TAG,
|
||||
+ "Invalid surface bits command rectangle: %" PRIu16 "x%" PRIu16 "-%" PRIu16
|
||||
+ "x%" PRIu16 " does not fit %" PRIu32 "x%" PRIu32,
|
||||
+ cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom,
|
||||
+ context->settings->DesktopWidth, context->settings->DesktopHeight);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT16 cmdType)
|
||||
{
|
||||
SURFACE_BITS_COMMAND cmd = { 0 };
|
||||
@@ -98,6 +142,9 @@
|
||||
Stream_Read_UINT16(s, cmd.destRight);
|
||||
Stream_Read_UINT16(s, cmd.destBottom);
|
||||
|
||||
+ if (!update_recv_surfcmd_is_rect_valid(update->context, &cmd))
|
||||
+ goto fail;
|
||||
+
|
||||
if (!update_recv_surfcmd_bitmap_ex(s, &cmd.bmp))
|
||||
goto fail;
|
||||
|
||||
--- a/libfreerdp/core/update.c
|
||||
+++ b/libfreerdp/core/update.c
|
||||
@@ -99,6 +99,13 @@
|
||||
Stream_Read_UINT16(s, bitmapData->flags);
|
||||
Stream_Read_UINT16(s, bitmapData->bitmapLength);
|
||||
|
||||
+ if ((bitmapData->width == 0) || (bitmapData->height == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "Invalid BITMAP_DATA: width=%" PRIu16 ", height=%" PRIu16, bitmapData->width,
|
||||
+ bitmapData->height);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if (bitmapData->flags & BITMAP_COMPRESSION)
|
||||
{
|
||||
if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR))
|
||||
100
debian/patches/0052-CVE-2022-24883.patch
vendored
Normal file
100
debian/patches/0052-CVE-2022-24883.patch
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
Description: CVE-2022-24883 - FreeRDP Server authentication might allow invalid credentials to pass
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/6f473b273a4b6f0cb6aca32b95e22fd0de88e144
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-qxm3-v2r6-vmwf
|
||||
From 6f473b273a4b6f0cb6aca32b95e22fd0de88e144 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Fri, 22 Apr 2022 14:42:11 +0200
|
||||
Subject: [PATCH] Cleaned up ntlm_fetch_ntlm_v2_hash
|
||||
|
||||
(cherry picked from commit 4661492e5a617199457c8074bad22f766a116cdc)
|
||||
---
|
||||
winpr/libwinpr/sspi/NTLM/ntlm_compute.c | 58 +++++++++++--------------
|
||||
1 file changed, 25 insertions(+), 33 deletions(-)
|
||||
|
||||
--- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c
|
||||
+++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c
|
||||
@@ -206,59 +206,48 @@
|
||||
ntlm_current_time(context->Timestamp);
|
||||
}
|
||||
|
||||
-static int ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
+static BOOL ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
{
|
||||
- WINPR_SAM* sam;
|
||||
- WINPR_SAM_ENTRY* entry;
|
||||
+ BOOL rc = FALSE;
|
||||
+ WINPR_SAM* sam = NULL;
|
||||
+ WINPR_SAM_ENTRY* entry = NULL;
|
||||
SSPI_CREDENTIALS* credentials = context->credentials;
|
||||
sam = SamOpen(context->SamFile, TRUE);
|
||||
|
||||
if (!sam)
|
||||
- return -1;
|
||||
+ goto fail;
|
||||
|
||||
entry = SamLookupUserW(
|
||||
- sam, (LPWSTR)credentials->identity.User, credentials->identity.UserLength * 2,
|
||||
- (LPWSTR)credentials->identity.Domain, credentials->identity.DomainLength * 2);
|
||||
+ sam, (LPWSTR)credentials->identity.User, credentials->identity.UserLength * sizeof(WCHAR),
|
||||
+ (LPWSTR)credentials->identity.Domain, credentials->identity.DomainLength * sizeof(WCHAR));
|
||||
|
||||
- if (entry)
|
||||
+ if (!entry)
|
||||
{
|
||||
-#ifdef WITH_DEBUG_NTLM
|
||||
- WLog_DBG(TAG, "NTLM Hash:");
|
||||
- winpr_HexDump(TAG, WLOG_DEBUG, entry->NtHash, 16);
|
||||
-#endif
|
||||
- NTOWFv2FromHashW(entry->NtHash, (LPWSTR)credentials->identity.User,
|
||||
- credentials->identity.UserLength * 2, (LPWSTR)credentials->identity.Domain,
|
||||
- credentials->identity.DomainLength * 2, (BYTE*)hash);
|
||||
- SamFreeEntry(sam, entry);
|
||||
- SamClose(sam);
|
||||
- return 1;
|
||||
+ entry = SamLookupUserW(sam, (LPWSTR)credentials->identity.User,
|
||||
+ credentials->identity.UserLength * sizeof(WCHAR), NULL, 0);
|
||||
}
|
||||
+
|
||||
+ if (!entry)
|
||||
+ goto fail;
|
||||
|
||||
- entry = SamLookupUserW(sam, (LPWSTR)credentials->identity.User,
|
||||
- credentials->identity.UserLength * 2, NULL, 0);
|
||||
-
|
||||
- if (entry)
|
||||
- {
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
WLog_DBG(TAG, "NTLM Hash:");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, entry->NtHash, 16);
|
||||
#endif
|
||||
- NTOWFv2FromHashW(entry->NtHash, (LPWSTR)credentials->identity.User,
|
||||
- credentials->identity.UserLength * 2, (LPWSTR)credentials->identity.Domain,
|
||||
- credentials->identity.DomainLength * 2, (BYTE*)hash);
|
||||
- SamFreeEntry(sam, entry);
|
||||
- SamClose(sam);
|
||||
- return 1;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- SamClose(sam);
|
||||
- WLog_ERR(TAG, "Error: Could not find user in SAM database");
|
||||
- return 0;
|
||||
- }
|
||||
|
||||
+ NTOWFv2FromHashW(entry->NtHash, (LPWSTR)credentials->identity.User,
|
||||
+ credentials->identity.UserLength * sizeof(WCHAR),
|
||||
+ (LPWSTR)credentials->identity.Domain,
|
||||
+ credentials->identity.DomainLength * sizeof(WCHAR), (BYTE*)hash);
|
||||
+
|
||||
+ rc = TRUE;
|
||||
+
|
||||
+fail:
|
||||
+ SamFreeEntry(sam, entry);
|
||||
SamClose(sam);
|
||||
- return 1;
|
||||
+ if (!rc)
|
||||
+ WLog_ERR(TAG, "Error: Could not find user in SAM database");
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static int ntlm_convert_password_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
50
debian/patches/0053-CVE-2022-39316.patch
vendored
Normal file
50
debian/patches/0053-CVE-2022-39316.patch
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
Description: CVE-2022-39316 - Out of bound read in zgfx decoder
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/e865c24efc40ebc52e75979c94cdd4ee2c1495b0.patch
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-5w4j-mrrh-jjrm
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024511
|
||||
From e865c24efc40ebc52e75979c94cdd4ee2c1495b0 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 09:09:28 +0200
|
||||
Subject: [PATCH] Added missing length checks in zgfx_decompress_segment
|
||||
|
||||
(cherry picked from commit 64716b335858109d14f27b51acc4c4d71a92a816)
|
||||
---
|
||||
libfreerdp/codec/zgfx.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/libfreerdp/codec/zgfx.c
|
||||
+++ b/libfreerdp/codec/zgfx.c
|
||||
@@ -230,19 +230,19 @@
|
||||
BYTE* pbSegment;
|
||||
size_t cbSegment;
|
||||
|
||||
- if (!zgfx || !stream)
|
||||
+ if (!zgfx || !stream || (segmentSize < 2))
|
||||
return FALSE;
|
||||
|
||||
cbSegment = segmentSize - 1;
|
||||
|
||||
- if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1) ||
|
||||
- (segmentSize > UINT32_MAX))
|
||||
+ if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize > UINT32_MAX))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(stream, flags); /* header (1 byte) */
|
||||
zgfx->OutputCount = 0;
|
||||
pbSegment = Stream_Pointer(stream);
|
||||
- Stream_Seek(stream, cbSegment);
|
||||
+ if (!Stream_SafeSeek(stream, cbSegment))
|
||||
+ return FALSE;
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
{
|
||||
@@ -350,6 +350,9 @@
|
||||
if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount)
|
||||
return FALSE;
|
||||
|
||||
+ if (count > zgfx->cBitsRemaining / 8)
|
||||
+ return FALSE;
|
||||
+
|
||||
CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent,
|
||||
count);
|
||||
zgfx_history_buffer_ring_write(zgfx, zgfx->pbInputCurrent, count);
|
||||
38
debian/patches/0054-CVE-2022-39318.patch
vendored
Normal file
38
debian/patches/0054-CVE-2022-39318.patch
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
Description: CVE-2022-39318 - Division by zero in urbdrc channel
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/80adde17ddc4b596ed1dae0922a0c54ab3d4b8ea.patch
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-387j-8j96-7q35
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024511
|
||||
From 80adde17ddc4b596ed1dae0922a0c54ab3d4b8ea Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 08:27:41 +0200
|
||||
Subject: [PATCH] Fixed division by zero in urbdrc
|
||||
|
||||
(cherry picked from commit 731f8419d04b481d7160de1f34062d630ed48765)
|
||||
---
|
||||
channels/urbdrc/client/libusb/libusb_udevice.c | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||
+++ b/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||
@@ -1214,12 +1214,18 @@
|
||||
else
|
||||
Stream_Seek(user_data->data, (NumberOfPackets * 12));
|
||||
|
||||
- iso_packet_size = BufferSize / NumberOfPackets;
|
||||
- iso_transfer = libusb_alloc_transfer(NumberOfPackets);
|
||||
+ if (NumberOfPackets > 0)
|
||||
+ {
|
||||
+ iso_packet_size = BufferSize / NumberOfPackets;
|
||||
+ iso_transfer = libusb_alloc_transfer((int)NumberOfPackets);
|
||||
+ }
|
||||
|
||||
if (iso_transfer == NULL)
|
||||
{
|
||||
- WLog_Print(urbdrc->log, WLOG_ERROR, "Error: libusb_alloc_transfer.");
|
||||
+ WLog_Print(urbdrc->log, WLOG_ERROR,
|
||||
+ "Error: libusb_alloc_transfer [NumberOfPackets=%" PRIu32 ", BufferSize=%" PRIu32
|
||||
+ " ]",
|
||||
+ NumberOfPackets, BufferSize);
|
||||
async_transfer_user_data_free(user_data);
|
||||
return -1;
|
||||
}
|
||||
68
debian/patches/0055-CVE-2022-39319.patch
vendored
Normal file
68
debian/patches/0055-CVE-2022-39319.patch
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
Description: CVE-2022-39319 - Missing length validation in urbdrc channel
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/11555828d2cf289b350baba5ad1f462f10b80b76
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-mvxm-wfj2-5fvh
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024511
|
||||
From 11555828d2cf289b350baba5ad1f462f10b80b76 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 08:47:51 +0200
|
||||
Subject: [PATCH] Fixed missing input buffer length check in urbdrc
|
||||
|
||||
(cherry picked from commit 497df00f741dd4fc89292aaef2db7368aee45d0d)
|
||||
---
|
||||
channels/urbdrc/client/data_transfer.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
--- a/channels/urbdrc/client/data_transfer.c
|
||||
+++ b/channels/urbdrc/client/data_transfer.c
|
||||
@@ -29,6 +29,10 @@
|
||||
#include "urbdrc_types.h"
|
||||
#include "data_transfer.h"
|
||||
|
||||
+#define Stream_CheckAndLogRequiredLength(tag, s, len) \
|
||||
+ Stream_CheckAndLogRequiredLengthWLogEx(WLog_Get(tag), WLOG_WARN, s, len, "%s(%s:%" PRIuz ")", __FUNCTION__, \
|
||||
+ __FILE__, __LINE__)
|
||||
+
|
||||
static void usb_process_get_port_status(IUDEVICE* pdev, wStream* out)
|
||||
{
|
||||
int bcdUSB = pdev->query_device_descriptor(pdev, BCD_USB);
|
||||
@@ -241,6 +245,10 @@
|
||||
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
Stream_Read_UINT32(s, RequestId);
|
||||
+
|
||||
+ if (OutputBufferSize > UINT32_MAX - 4)
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+
|
||||
InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
|
||||
out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, OutputBufferSize + 4);
|
||||
|
||||
@@ -720,6 +728,15 @@
|
||||
Stream_Read_UINT32(s, TransferFlags); /** TransferFlags */
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
EndpointAddress = (PipeHandle & 0x000000ff);
|
||||
+
|
||||
+ if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
+ {
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
+ {
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/** process TS_URB_BULK_OR_INTERRUPT_TRANSFER */
|
||||
return pdev->bulk_or_interrupt_transfer(pdev, callback, MessageId, RequestId, EndpointAddress,
|
||||
TransferFlags, noAck, OutputBufferSize,
|
||||
@@ -803,6 +820,13 @@
|
||||
packetDescriptorData = Stream_Pointer(s);
|
||||
Stream_Seek(s, NumberOfPackets * 12);
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
+
|
||||
+ if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
+ {
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+ }
|
||||
+
|
||||
return pdev->isoch_transfer(
|
||||
pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, StartFrame,
|
||||
ErrorCount, noAck, packetDescriptorData, NumberOfPackets, OutputBufferSize,
|
||||
329
debian/patches/0056-CVE-2022-39347.patch
vendored
Normal file
329
debian/patches/0056-CVE-2022-39347.patch
vendored
Normal file
@ -0,0 +1,329 @@
|
||||
Description: CVE-2022-39347 - Missing path sanitation with `drive` channel
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/027424c2c6c0991cb9c22f9511478229c9b17e5d
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-c5xq-8v35-pffg
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024511
|
||||
From 027424c2c6c0991cb9c22f9511478229c9b17e5d Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Mon, 24 Oct 2022 10:41:55 +0200
|
||||
Subject: [PATCH] Fixed path validation in drive channel
|
||||
|
||||
Check that canonical path is a subpath of the shared directory
|
||||
|
||||
(cherry picked from commit 844c94e6d0438fa7bd8ff8d5513c3f69c3018b85)
|
||||
---
|
||||
channels/drive/client/drive_file.c | 106 ++++++++++++++++++-----------
|
||||
channels/drive/client/drive_file.h | 8 +--
|
||||
channels/drive/client/drive_main.c | 8 +--
|
||||
3 files changed, 73 insertions(+), 49 deletions(-)
|
||||
|
||||
--- a/channels/drive/client/drive_file.c
|
||||
+++ b/channels/drive/client/drive_file.c
|
||||
@@ -45,6 +45,45 @@
|
||||
|
||||
#include "drive_file.h"
|
||||
|
||||
+#include <assert.h>
|
||||
+
|
||||
+
|
||||
+static int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||
+{
|
||||
+ assert(string1);
|
||||
+ assert(string2);
|
||||
+
|
||||
+ for (size_t x = 0; x < count; x++)
|
||||
+ {
|
||||
+ const WCHAR a = string1[x];
|
||||
+ const WCHAR b = string2[x];
|
||||
+
|
||||
+ if (a != b)
|
||||
+ return (int)a - b;
|
||||
+ else if ((a == '\0') || (b == '\0'))
|
||||
+ return (int)a - b;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static WCHAR* _wcsstr(const WCHAR* str, const WCHAR* strSearch)
|
||||
+{
|
||||
+ assert(str);
|
||||
+ assert(strSearch);
|
||||
+
|
||||
+ if (strSearch[0] == '\0')
|
||||
+ return (WCHAR*)str;
|
||||
+
|
||||
+ const size_t searchLen = _wcslen(strSearch);
|
||||
+ while (*str)
|
||||
+ {
|
||||
+ if (_wcsncmp(str, strSearch, searchLen) == 0)
|
||||
+ return (WCHAR*)str;
|
||||
+ str++;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
#ifdef WITH_DEBUG_RDPDR
|
||||
#define DEBUG_WSTR(msg, wstr) \
|
||||
do \
|
||||
@@ -61,10 +100,14 @@
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
-static void drive_file_fix_path(WCHAR* path)
|
||||
+static BOOL drive_file_fix_path(WCHAR* path, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
- size_t length = _wcslen(path);
|
||||
+
|
||||
+ if ((length == 0) || (length > UINT32_MAX))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ assert(path);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
@@ -75,58 +118,82 @@
|
||||
#ifdef WIN32
|
||||
|
||||
if ((length == 3) && (path[1] == L':') && (path[2] == L'/'))
|
||||
- return;
|
||||
+ return FALSE;
|
||||
|
||||
#else
|
||||
|
||||
if ((length == 1) && (path[0] == L'/'))
|
||||
- return;
|
||||
+ return FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
if ((length > 0) && (path[length - 1] == L'/'))
|
||||
path[length - 1] = L'\0';
|
||||
+
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
static WCHAR* drive_file_combine_fullpath(const WCHAR* base_path, const WCHAR* path,
|
||||
- size_t PathLength)
|
||||
+ size_t PathWCharLength)
|
||||
{
|
||||
- WCHAR* fullpath;
|
||||
- size_t base_path_length;
|
||||
+ BOOL ok = FALSE;
|
||||
+ WCHAR* fullpath = NULL;
|
||||
+ size_t length;
|
||||
|
||||
- if (!base_path || (!path && (PathLength > 0)))
|
||||
- return NULL;
|
||||
+ if (!base_path || (!path && (PathWCharLength > 0)))
|
||||
+ goto fail;
|
||||
|
||||
- base_path_length = _wcslen(base_path) * 2;
|
||||
- fullpath = (WCHAR*)calloc(1, base_path_length + PathLength + sizeof(WCHAR));
|
||||
+ const size_t base_path_length = _wcsnlen(base_path, MAX_PATH);
|
||||
+ length = base_path_length + PathWCharLength + 1;
|
||||
+ fullpath = (WCHAR*)calloc(length, sizeof(WCHAR));
|
||||
|
||||
if (!fullpath)
|
||||
+ goto fail;
|
||||
+
|
||||
+ CopyMemory(fullpath, base_path, base_path_length * sizeof(WCHAR));
|
||||
+ if (path)
|
||||
+ CopyMemory(&fullpath[base_path_length], path, PathWCharLength * sizeof(WCHAR));
|
||||
+
|
||||
+ if (!drive_file_fix_path(fullpath, length))
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* Ensure the path does not contain sequences like '..' */
|
||||
+ const WCHAR dotdot[] = { '.', '.', '\0' };
|
||||
+ if (_wcsstr(&fullpath[base_path_length], dotdot))
|
||||
{
|
||||
- WLog_ERR(TAG, "malloc failed!");
|
||||
- return NULL;
|
||||
+ char abuffer[MAX_PATH] = { 0 };
|
||||
+ ConvertFromUnicode(CP_UTF8, 0, &fullpath[base_path_length], -1, (char**)&abuffer,
|
||||
+ ARRAYSIZE(abuffer) - 1, NULL, NULL);
|
||||
+
|
||||
+ WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' from server, aborting!",
|
||||
+ &abuffer[base_path_length]);
|
||||
+ goto fail;
|
||||
}
|
||||
|
||||
- CopyMemory(fullpath, base_path, base_path_length);
|
||||
- if (path)
|
||||
- CopyMemory((char*)fullpath + base_path_length, path, PathLength);
|
||||
- drive_file_fix_path(fullpath);
|
||||
+ ok = TRUE;
|
||||
+fail:
|
||||
+ if (!ok)
|
||||
+ {
|
||||
+ free(fullpath);
|
||||
+ fullpath = NULL;
|
||||
+ }
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
{
|
||||
- WIN32_FIND_DATAW findFileData;
|
||||
+ WIN32_FIND_DATAW findFileData = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
- HANDLE dir;
|
||||
- WCHAR* fullpath;
|
||||
- WCHAR* path_slash;
|
||||
- size_t base_path_length;
|
||||
+ HANDLE dir = INVALID_HANDLE_VALUE;
|
||||
+ WCHAR* fullpath = NULL;
|
||||
+ WCHAR* path_slash = NULL;
|
||||
+ size_t base_path_length = 0;
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
- base_path_length = _wcslen(path) * 2;
|
||||
- path_slash = (WCHAR*)calloc(1, base_path_length + sizeof(WCHAR) * 3);
|
||||
+ base_path_length = _wcslen(path);
|
||||
+ path_slash = (WCHAR*)calloc(base_path_length + 3, sizeof(WCHAR));
|
||||
|
||||
if (!path_slash)
|
||||
{
|
||||
@@ -134,12 +201,11 @@
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- CopyMemory(path_slash, path, base_path_length);
|
||||
- path_slash[base_path_length / 2] = L'/';
|
||||
- path_slash[base_path_length / 2 + 1] = L'*';
|
||||
+ CopyMemory(path_slash, path, base_path_length * sizeof(WCHAR));
|
||||
+ path_slash[base_path_length] = L'/';
|
||||
+ path_slash[base_path_length + 1] = L'*';
|
||||
DEBUG_WSTR("Search in %s", path_slash);
|
||||
dir = FindFirstFileW(path_slash, &findFileData);
|
||||
- path_slash[base_path_length / 2 + 1] = 0;
|
||||
|
||||
if (dir == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -149,7 +215,7 @@
|
||||
|
||||
do
|
||||
{
|
||||
- size_t len = _wcslen(findFileData.cFileName);
|
||||
+ const size_t len = _wcsnlen(findFileData.cFileName, ARRAYSIZE(findFileData.cFileName));
|
||||
|
||||
if ((len == 1 && findFileData.cFileName[0] == L'.') ||
|
||||
(len == 2 && findFileData.cFileName[0] == L'.' && findFileData.cFileName[1] == L'.'))
|
||||
@@ -157,7 +223,7 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
- fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len * 2);
|
||||
+ fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len);
|
||||
DEBUG_WSTR("Delete %s", fullpath);
|
||||
|
||||
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
@@ -333,13 +399,13 @@
|
||||
return file->file_handle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
-DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||
- UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||
- UINT32 FileAttributes, UINT32 SharedAccess)
|
||||
+DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||
+ UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||
+ UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
|
||||
- if (!base_path || (!path && (PathLength > 0)))
|
||||
+ if (!base_path || (!path && (PathWCharLength > 0)))
|
||||
return NULL;
|
||||
|
||||
file = (DRIVE_FILE*)calloc(1, sizeof(DRIVE_FILE));
|
||||
@@ -359,7 +425,7 @@
|
||||
file->CreateDisposition = CreateDisposition;
|
||||
file->CreateOptions = CreateOptions;
|
||||
file->SharedAccess = SharedAccess;
|
||||
- drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathLength));
|
||||
+ drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathWCharLength));
|
||||
|
||||
if (!drive_file_init(file))
|
||||
{
|
||||
@@ -714,13 +780,10 @@
|
||||
return FALSE;
|
||||
|
||||
fullpath = drive_file_combine_fullpath(file->basepath, (WCHAR*)Stream_Pointer(input),
|
||||
- FileNameLength);
|
||||
+ FileNameLength / sizeof(WCHAR));
|
||||
|
||||
if (!fullpath)
|
||||
- {
|
||||
- WLog_ERR(TAG, "drive_file_combine_fullpath failed!");
|
||||
return FALSE;
|
||||
- }
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -759,7 +822,7 @@
|
||||
}
|
||||
|
||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||
- const WCHAR* path, UINT32 PathLength, wStream* output)
|
||||
+ const WCHAR* path, UINT32 PathWCharLength, wStream* output)
|
||||
{
|
||||
size_t length;
|
||||
WCHAR* ent_path;
|
||||
@@ -773,7 +836,7 @@
|
||||
if (file->find_handle != INVALID_HANDLE_VALUE)
|
||||
FindClose(file->find_handle);
|
||||
|
||||
- ent_path = drive_file_combine_fullpath(file->basepath, path, PathLength);
|
||||
+ ent_path = drive_file_combine_fullpath(file->basepath, path, PathWCharLength);
|
||||
/* open new search handle and retrieve the first entry */
|
||||
file->find_handle = FindFirstFileW(ent_path, &file->find_data);
|
||||
free(ent_path);
|
||||
--- a/channels/drive/client/drive_file.h
|
||||
+++ b/channels/drive/client/drive_file.h
|
||||
@@ -51,9 +51,9 @@
|
||||
UINT32 CreateOptions;
|
||||
};
|
||||
|
||||
-DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||
- UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||
- UINT32 FileAttributes, UINT32 SharedAccess);
|
||||
+DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||
+ UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||
+ UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess);
|
||||
BOOL drive_file_free(DRIVE_FILE* file);
|
||||
|
||||
BOOL drive_file_open(DRIVE_FILE* file);
|
||||
@@ -64,6 +64,6 @@
|
||||
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
|
||||
wStream* input);
|
||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||
- const WCHAR* path, UINT32 PathLength, wStream* output);
|
||||
+ const WCHAR* path, UINT32 PathWCharLength, wStream* output);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_DRIVE_FILE_H */
|
||||
--- a/channels/drive/client/drive_main.c
|
||||
+++ b/channels/drive/client/drive_main.c
|
||||
@@ -184,8 +184,8 @@
|
||||
|
||||
path = (const WCHAR*)Stream_Pointer(irp->input);
|
||||
FileId = irp->devman->id_sequence++;
|
||||
- file = drive_file_new(drive->path, path, PathLength, FileId, DesiredAccess, CreateDisposition,
|
||||
- CreateOptions, FileAttributes, SharedAccess);
|
||||
+ file = drive_file_new(drive->path, path, PathLength / sizeof(WCHAR), FileId, DesiredAccess,
|
||||
+ CreateDisposition, CreateOptions, FileAttributes, SharedAccess);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
@@ -636,8 +636,8 @@
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Stream_Write_UINT32(irp->output, 0); /* Length */
|
||||
}
|
||||
- else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path, PathLength,
|
||||
- irp->output))
|
||||
+ else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path,
|
||||
+ PathLength / sizeof(WCHAR), irp->output))
|
||||
{
|
||||
irp->IoStatus = drive_map_windows_err(GetLastError());
|
||||
}
|
||||
38
debian/patches/0057-CVE-2022-41877.patch
vendored
Normal file
38
debian/patches/0057-CVE-2022-41877.patch
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
Description: CVE-2022-41877
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/6655841cf2a00b764f855040aecb8803cfc5eaba
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-pmv3-wpw4-pw5h
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024511
|
||||
From 6655841cf2a00b764f855040aecb8803cfc5eaba Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Mon, 24 Oct 2022 08:45:05 +0200
|
||||
Subject: [PATCH] Fixed missing stream length check in
|
||||
drive_file_query_directory
|
||||
|
||||
(cherry picked from commit 4e4bb79795d6ac85473fb7a83e53ccf63d204b93)
|
||||
---
|
||||
channels/drive/client/drive_main.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/channels/drive/client/drive_main.c
|
||||
+++ b/channels/drive/client/drive_main.c
|
||||
@@ -46,6 +46,10 @@
|
||||
|
||||
#include "drive_file.h"
|
||||
|
||||
+#define Stream_CheckAndLogRequiredLength(tag, s, len) \
|
||||
+ Stream_CheckAndLogRequiredLengthWLogEx(WLog_Get(tag), WLOG_WARN, s, len, "%s(%s:%" PRIuz ")", __FUNCTION__, \
|
||||
+ __FILE__, __LINE__)
|
||||
+
|
||||
typedef struct _DRIVE_DEVICE DRIVE_DEVICE;
|
||||
|
||||
struct _DRIVE_DEVICE
|
||||
@@ -629,6 +633,9 @@
|
||||
Stream_Read_UINT32(irp->input, PathLength);
|
||||
Stream_Seek(irp->input, 23); /* Padding */
|
||||
path = (WCHAR*)Stream_Pointer(irp->input);
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, PathLength))
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
38
debian/patches/0058-CVE-2022-39282.patch
vendored
Normal file
38
debian/patches/0058-CVE-2022-39282.patch
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
Description: CVE-2022-39282 - RDP client: Read of uninitialized memory with parallel port redirection
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/60aac2abf0740dd36b62712fba91498fd6e055fe
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-c45q-wcpg-mxjq
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1021659
|
||||
From 60aac2abf0740dd36b62712fba91498fd6e055fe Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 6 Oct 2022 09:12:40 +0200
|
||||
Subject: [PATCH] Fix length checks in parallel driver
|
||||
|
||||
The length requested was not checked against the length read from
|
||||
the port.
|
||||
|
||||
(cherry picked from commit 094cc5a4596c299595b732effd59ee149181fd61)
|
||||
---
|
||||
channels/parallel/client/parallel_main.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c
|
||||
index af3e82703a60..993605a65e23 100644
|
||||
--- a/channels/parallel/client/parallel_main.c
|
||||
+++ b/channels/parallel/client/parallel_main.c
|
||||
@@ -159,7 +159,7 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp)
|
||||
return ERROR_INVALID_DATA;
|
||||
Stream_Read_UINT32(irp->input, Length);
|
||||
Stream_Read_UINT64(irp->input, Offset);
|
||||
- buffer = (BYTE*)malloc(Length);
|
||||
+ buffer = (BYTE*)calloc(Length, sizeof(BYTE));
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
@@ -178,6 +178,7 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp)
|
||||
}
|
||||
else
|
||||
{
|
||||
+ Length = status;
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(irp->output, Length);
|
||||
39
debian/patches/0059-CVE-2022-39283.patch
vendored
Normal file
39
debian/patches/0059-CVE-2022-39283.patch
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
Description: CVE-2022-39283 - RDP client might read out of bounds data and display it
|
||||
Origin: https://github.com/FreeRDP/FreeRDP/commit/be793c3bb776c1bbda9156b427408d5a5eb00f70
|
||||
Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-6cf9-3328-qrvh
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1021659
|
||||
From be793c3bb776c1bbda9156b427408d5a5eb00f70 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 6 Oct 2022 09:15:40 +0200
|
||||
Subject: [PATCH] Fixed missing length check in video channel
|
||||
|
||||
Data received in video redirection channel was not checked for
|
||||
proper length.
|
||||
|
||||
(cherry picked from commit eeffd1050e9284d1464b58e049b2b4d88726632b)
|
||||
---
|
||||
channels/video/client/video_main.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/channels/video/client/video_main.c
|
||||
+++ b/channels/video/client/video_main.c
|
||||
@@ -46,6 +46,10 @@
|
||||
|
||||
#include "video_main.h"
|
||||
|
||||
+#define Stream_CheckAndLogRequiredLength(tag, s, len) \
|
||||
+ Stream_CheckAndLogRequiredLengthWLogEx(WLog_Get(tag), WLOG_WARN, s, len, "%s(%s:%" PRIuz ")", __FUNCTION__, \
|
||||
+ __FILE__, __LINE__)
|
||||
+
|
||||
struct _VIDEO_CHANNEL_CALLBACK
|
||||
{
|
||||
IWTSVirtualChannelCallback iface;
|
||||
@@ -930,6 +934,8 @@
|
||||
Stream_Read_UINT16(s, data.PacketsInSample);
|
||||
Stream_Read_UINT32(s, data.SampleNumber);
|
||||
Stream_Read_UINT32(s, data.cbSample);
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, data.cbSample))
|
||||
+ return ERROR_INVALID_DATA;
|
||||
data.pSample = Stream_Pointer(s);
|
||||
|
||||
/*
|
||||
38
debian/patches/1001_keep-symbol-DumpThreadHandles-if-debugging-is-disabled.patch
vendored
Normal file
38
debian/patches/1001_keep-symbol-DumpThreadHandles-if-debugging-is-disabled.patch
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
Description: Keep DumpThreadHandles as a symbol even if WITH_DEBUG_THREADS is OFF.
|
||||
Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
|
||||
Forwarded: https://github.com/FreeRDP/FreeRDP/pull/7708
|
||||
|
||||
--- a/winpr/libwinpr/thread/thread.c
|
||||
+++ b/winpr/libwinpr/thread/thread.c
|
||||
@@ -760,9 +760,9 @@
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-#if defined(WITH_DEBUG_THREADS)
|
||||
VOID DumpThreadHandles(void)
|
||||
{
|
||||
+#if defined(WITH_DEBUG_THREADS)
|
||||
char** msg;
|
||||
size_t used, i;
|
||||
void* stack = winpr_backtrace(20);
|
||||
@@ -823,6 +823,6 @@
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "---------------- End Dumping thread handles -------------");
|
||||
-}
|
||||
#endif
|
||||
+}
|
||||
#endif
|
||||
--- a/winpr/include/winpr/thread.h
|
||||
+++ b/winpr/include/winpr/thread.h
|
||||
@@ -245,10 +245,7 @@
|
||||
/* CommandLineToArgvA is not present in the original Windows API, WinPR always exports it */
|
||||
|
||||
WINPR_API LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs);
|
||||
-
|
||||
-#if defined(WITH_DEBUG_THREADS)
|
||||
WINPR_API VOID DumpThreadHandles(void);
|
||||
-#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
26
debian/patches/series
vendored
26
debian/patches/series
vendored
@ -22,3 +22,29 @@
|
||||
0033-Reverted-winpr_BinToHexString-argument-change.patch
|
||||
0034-Fixed-6938-Remote-app-mode-clipboard-fix.patch
|
||||
0035-Fixed-6989-Use-X509_STORE_set_default_paths.patch
|
||||
1001_keep-symbol-DumpThreadHandles-if-debugging-is-disabled.patch
|
||||
0036-CVE-2023-39350.patch
|
||||
0037-CVE-2023-39351.patch
|
||||
0038-CVE-2023-39352.patch
|
||||
0039-CVE-2023-39353-part1.patch
|
||||
0039-CVE-2023-39353-part2.patch
|
||||
0040-CVE-2023-39354-part1.patch
|
||||
0040-CVE-2023-39354-part2.patch
|
||||
0041-CVE-2023-39355.patch
|
||||
0042-CVE-2023-39356-part1.patch
|
||||
0043-CVE-2023-39356-part2.patch
|
||||
0044-CVE-2023-40567.patch
|
||||
0045-CVE-2023-40181.patch
|
||||
0046-CVE-2023-40186.patch
|
||||
0047-CVE-2023-40188.patch
|
||||
0048-CVE-2023-40569.patch
|
||||
0049-CVE-2023-40589.patch
|
||||
0050-CVE-2021-41160.patch
|
||||
0052-CVE-2022-24883.patch
|
||||
0053-CVE-2022-39316.patch
|
||||
0054-CVE-2022-39318.patch
|
||||
0055-CVE-2022-39319.patch
|
||||
0056-CVE-2022-39347.patch
|
||||
0057-CVE-2022-41877.patch
|
||||
0058-CVE-2022-39282.patch
|
||||
0059-CVE-2022-39283.patch
|
||||
|
||||
2
debian/rules
vendored
2
debian/rules
vendored
@ -19,7 +19,7 @@ DEB_CMAKE_EXTRA_FLAGS = \
|
||||
-DCMAKE_SKIP_RPATH=FALSE \
|
||||
-DCMAKE_SKIP_INSTALL_RPATH=TRUE \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DWITH_DEBUG_ALL=ON \
|
||||
-DWITH_DEBUG_ALL=OFF \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DWITH_CHANNELS=ON \
|
||||
-DBUILTIN_CHANNELS=ON \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user