CVE-2020-11095 (published 2020-06-22T22:15Z)

In FreeRDP before version 2.1.2, an out of bound reads occurs resulting in accessing a memory location that is outside of the boundaries of the static array PRIMARY_DRAWING_ORDER_FIELD_BYTES. This is fixed in version 2.1.2.

Severity: MEDIUM
CVSS v2 base score: 5.5 (AV:N/AC:L/Au:S/C:P/I:N/A:P)
CVSS v3 base score: 5.4, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L)

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/FreeRDP/FreeRDP
commit_details: repo_url: https://github.com/FreeRDP/FreeRDP
author: akallabeth
author_date: 2020-05-26 07:28:33+02:00
msg: Fixed invalid access in update_recv_primary_order

CVE-2020-11095 thanks @antonio-morales for finding this.
repository: repo_url: https://github.com/FreeRDP/FreeRDP
repo_name: FreeRDP/FreeRDP
description: FreeRDP is a free remote desktop protocol library and clients
repo_language: C
owner: FreeRDP
file_changes: filename: orders.c
change_type: ModificationType.MODIFY
diff: @@ -43,36 +43,75 @@
 
 #define TAG FREERDP_TAG("core.orders")
 
-const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[] = { DSTBLT_ORDER_FIELD_BYTES,
-	                                               PATBLT_ORDER_FIELD_BYTES,
-	                                               SCRBLT_ORDER_FIELD_BYTES,
-	                                               0,
-	                                               0,
-	                                               0,
-	                                               0,
-	                                               DRAW_NINE_GRID_ORDER_FIELD_BYTES,
-	                                               MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES,
-	                                               LINE_TO_ORDER_FIELD_BYTES,
-	                                               OPAQUE_RECT_ORDER_FIELD_BYTES,
-	                                               SAVE_BITMAP_ORDER_FIELD_BYTES,
-	                                               0,
-	                                               MEMBLT_ORDER_FIELD_BYTES,
-	                                               MEM3BLT_ORDER_FIELD_BYTES,
-	                                               MULTI_DSTBLT_ORDER_FIELD_BYTES,
-	                                               MULTI_PATBLT_ORDER_FIELD_BYTES,
-	                                               MULTI_SCRBLT_ORDER_FIELD_BYTES,
-	                                               MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES,
-	                                               FAST_INDEX_ORDER_FIELD_BYTES,
-	                                               POLYGON_SC_ORDER_FIELD_BYTES,
-	                                               POLYGON_CB_ORDER_FIELD_BYTES,
-	                                               POLYLINE_ORDER_FIELD_BYTES,
-	                                               0,
-	                                               FAST_GLYPH_ORDER_FIELD_BYTES,
-	                                               ELLIPSE_SC_ORDER_FIELD_BYTES,
-	                                               ELLIPSE_CB_ORDER_FIELD_BYTES,
-	                                               GLYPH_INDEX_ORDER_FIELD_BYTES };
-
-#define PRIMARY_DRAWING_ORDER_COUNT (ARRAYSIZE(PRIMARY_DRAWING_ORDER_FIELD_BYTES))
+BYTE get_primary_drawing_order_field_bytes(UINT32 orderType, BOOL* pValid)
+{
+	if (pValid)
+		*pValid = TRUE;
+	switch (orderType)
+	{
+		case 0:
+			return DSTBLT_ORDER_FIELD_BYTES;
+		case 1:
+			return PATBLT_ORDER_FIELD_BYTES;
+		case 2:
+			return SCRBLT_ORDER_FIELD_BYTES;
+		case 3:
+			return 0;
+		case 4:
+			return 0;
+		case 5:
+			return 0;
+		case 6:
+			return 0;
+		case 7:
+			return DRAW_NINE_GRID_ORDER_FIELD_BYTES;
+		case 8:
+			return MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES;
+		case 9:
+			return LINE_TO_ORDER_FIELD_BYTES;
+		case 10:
+			return OPAQUE_RECT_ORDER_FIELD_BYTES;
+		case 11:
+			return SAVE_BITMAP_ORDER_FIELD_BYTES;
+		case 12:
+			return 0;
+		case 13:
+			return MEMBLT_ORDER_FIELD_BYTES;
+		case 14:
+			return MEM3BLT_ORDER_FIELD_BYTES;
+		case 15:
+			return MULTI_DSTBLT_ORDER_FIELD_BYTES;
+		case 16:
+			return MULTI_PATBLT_ORDER_FIELD_BYTES;
+		case 17:
+			return MULTI_SCRBLT_ORDER_FIELD_BYTES;
+		case 18:
+			return MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES;
+		case 19:
+			return FAST_INDEX_ORDER_FIELD_BYTES;
+		case 20:
+			return POLYGON_SC_ORDER_FIELD_BYTES;
+		case 21:
+			return POLYGON_CB_ORDER_FIELD_BYTES;
+		case 22:
+			return POLYLINE_ORDER_FIELD_BYTES;
+		case 23:
+			return 0;
+		case 24:
+			return FAST_GLYPH_ORDER_FIELD_BYTES;
+		case 25:
+			return ELLIPSE_SC_ORDER_FIELD_BYTES;
+		case 26:
+			return ELLIPSE_CB_ORDER_FIELD_BYTES;
+		case 27:
+			return GLYPH_INDEX_ORDER_FIELD_BYTES;
+		default:
+			if (pValid)
+				*pValid = FALSE;
+			WLog_WARN(TAG, "Invalid orderType 0x%08X received", orderType);
+			return 0;
+	}
+}
 
 static const BYTE CBR2_BPP[] = { 0, 0, 0, 8, 16, 24, 32 };
 
@@ -3240,6 +3279,7 @@ static BOOL read_primary_order(wLog* log, const char* orderName, wStream* s,
 
 static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags)
 {
+	BYTE field;
 	BOOL rc = FALSE;
 	rdpContext* context = update->context;
 	rdpPrimaryUpdate* primary = update->primary;
@@ -3263,8 +3303,11 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags)
 	if (!check_primary_order_supported(update->log, settings, orderInfo->orderType, orderName))
 		return FALSE;
 
-	if (!update_read_field_flags(s, &(orderInfo->fieldFlags), flags,
-	                             PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]))
+	field = get_primary_drawing_order_field_bytes(orderInfo->orderType, &rc);
+	if (!rc)
+		return FALSE;
+
+	if (!update_read_field_flags(s, &(orderInfo->fieldFlags), flags, field))
 	{
 		WLog_Print(update->log, WLOG_ERROR, "update_read_field_flags() failed");
 		return FALSE;

programming_language: C
filename: orders.h
change_type: ModificationType.MODIFY
diff: @@ -189,7 +189,7 @@
 
 #define CG_GLYPH_UNICODE_PRESENT 0x0010
 
-FREERDP_LOCAL extern const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[];
+FREERDP_LOCAL BYTE get_primary_drawing_order_field_bytes(UINT32 orderType, BOOL* pValid);
 
 FREERDP_LOCAL BOOL update_recv_order(rdpUpdate* update, wStream* s);
 

programming_language: C
filename: update.c
change_type: ModificationType.MODIFY
diff: @@ -1087,7 +1087,7 @@ static int update_prepare_order_info(rdpContext* context, ORDER_INFO* orderInfo,
 	orderInfo->controlFlags = ORDER_STANDARD;
 	orderInfo->controlFlags |= ORDER_TYPE_CHANGE;
 	length += 1;
-	length += PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType];
+	length += get_primary_drawing_order_field_bytes(orderInfo->orderType, NULL);
 	length += update_prepare_bounds(context, orderInfo);
 	return length;
 }
@@ -1105,7 +1105,7 @@ static int update_write_order_info(rdpContext* context, wStream* s, ORDER_INFO*
 		Stream_Write_UINT8(s, orderInfo->orderType); /* orderType (1 byte) */
 
 	update_write_field_flags(s, orderInfo->fieldFlags, orderInfo->controlFlags,
-	                         PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]);
+	                         get_primary_drawing_order_field_bytes(orderInfo->orderType, NULL));
 	update_write_bounds(s, orderInfo);
 	Stream_SetPosition(s, position);
 	return 0;

programming_language: C