Backport upstream patch for CVE-2023-39356.

This commit is contained in:
Tobias Frost 2023-10-07 12:28:01 +02:00
parent ab18013d96
commit 09055cabae
5 changed files with 332 additions and 1 deletions

2
debian/changelog vendored
View File

@ -15,7 +15,7 @@ freerdp2 (2.3.0+dfsg1-2~deb10u3) UNRELEASED; urgency=medium
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-39354 CVE-2023-39355 CVE-2023-39356
-- Tobias Frost <tobi@debian.org> Mon, 02 Oct 2023 17:10:48 +0200

View 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)

View 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;

View File

@ -30,3 +30,6 @@
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