Skip to content

Commit 733ee32

Browse files
committed
Fixed invalid access in update_recv_primary_order
CVE-2020-11095 thanks @antonio-morales for finding this.
1 parent c3a1ed7 commit 733ee32

File tree

3 files changed

+78
-35
lines changed

3 files changed

+78
-35
lines changed

Diff for: libfreerdp/core/orders.c

+75-32
Original file line numberDiff line numberDiff line change
@@ -43,36 +43,75 @@
4343

4444
#define TAG FREERDP_TAG("core.orders")
4545

46-
const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[] = { DSTBLT_ORDER_FIELD_BYTES,
47-
PATBLT_ORDER_FIELD_BYTES,
48-
SCRBLT_ORDER_FIELD_BYTES,
49-
0,
50-
0,
51-
0,
52-
0,
53-
DRAW_NINE_GRID_ORDER_FIELD_BYTES,
54-
MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES,
55-
LINE_TO_ORDER_FIELD_BYTES,
56-
OPAQUE_RECT_ORDER_FIELD_BYTES,
57-
SAVE_BITMAP_ORDER_FIELD_BYTES,
58-
0,
59-
MEMBLT_ORDER_FIELD_BYTES,
60-
MEM3BLT_ORDER_FIELD_BYTES,
61-
MULTI_DSTBLT_ORDER_FIELD_BYTES,
62-
MULTI_PATBLT_ORDER_FIELD_BYTES,
63-
MULTI_SCRBLT_ORDER_FIELD_BYTES,
64-
MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES,
65-
FAST_INDEX_ORDER_FIELD_BYTES,
66-
POLYGON_SC_ORDER_FIELD_BYTES,
67-
POLYGON_CB_ORDER_FIELD_BYTES,
68-
POLYLINE_ORDER_FIELD_BYTES,
69-
0,
70-
FAST_GLYPH_ORDER_FIELD_BYTES,
71-
ELLIPSE_SC_ORDER_FIELD_BYTES,
72-
ELLIPSE_CB_ORDER_FIELD_BYTES,
73-
GLYPH_INDEX_ORDER_FIELD_BYTES };
74-
75-
#define PRIMARY_DRAWING_ORDER_COUNT (ARRAYSIZE(PRIMARY_DRAWING_ORDER_FIELD_BYTES))
46+
BYTE get_primary_drawing_order_field_bytes(UINT32 orderType, BOOL* pValid)
47+
{
48+
if (pValid)
49+
*pValid = TRUE;
50+
switch (orderType)
51+
{
52+
case 0:
53+
return DSTBLT_ORDER_FIELD_BYTES;
54+
case 1:
55+
return PATBLT_ORDER_FIELD_BYTES;
56+
case 2:
57+
return SCRBLT_ORDER_FIELD_BYTES;
58+
case 3:
59+
return 0;
60+
case 4:
61+
return 0;
62+
case 5:
63+
return 0;
64+
case 6:
65+
return 0;
66+
case 7:
67+
return DRAW_NINE_GRID_ORDER_FIELD_BYTES;
68+
case 8:
69+
return MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES;
70+
case 9:
71+
return LINE_TO_ORDER_FIELD_BYTES;
72+
case 10:
73+
return OPAQUE_RECT_ORDER_FIELD_BYTES;
74+
case 11:
75+
return SAVE_BITMAP_ORDER_FIELD_BYTES;
76+
case 12:
77+
return 0;
78+
case 13:
79+
return MEMBLT_ORDER_FIELD_BYTES;
80+
case 14:
81+
return MEM3BLT_ORDER_FIELD_BYTES;
82+
case 15:
83+
return MULTI_DSTBLT_ORDER_FIELD_BYTES;
84+
case 16:
85+
return MULTI_PATBLT_ORDER_FIELD_BYTES;
86+
case 17:
87+
return MULTI_SCRBLT_ORDER_FIELD_BYTES;
88+
case 18:
89+
return MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES;
90+
case 19:
91+
return FAST_INDEX_ORDER_FIELD_BYTES;
92+
case 20:
93+
return POLYGON_SC_ORDER_FIELD_BYTES;
94+
case 21:
95+
return POLYGON_CB_ORDER_FIELD_BYTES;
96+
case 22:
97+
return POLYLINE_ORDER_FIELD_BYTES;
98+
case 23:
99+
return 0;
100+
case 24:
101+
return FAST_GLYPH_ORDER_FIELD_BYTES;
102+
case 25:
103+
return ELLIPSE_SC_ORDER_FIELD_BYTES;
104+
case 26:
105+
return ELLIPSE_CB_ORDER_FIELD_BYTES;
106+
case 27:
107+
return GLYPH_INDEX_ORDER_FIELD_BYTES;
108+
default:
109+
if (pValid)
110+
*pValid = FALSE;
111+
WLog_WARN(TAG, "Invalid orderType 0x%08X received", orderType);
112+
return 0;
113+
}
114+
}
76115

77116
static const BYTE CBR2_BPP[] = { 0, 0, 0, 8, 16, 24, 32 };
78117

@@ -3240,6 +3279,7 @@ static BOOL read_primary_order(wLog* log, const char* orderName, wStream* s,
32403279

32413280
static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags)
32423281
{
3282+
BYTE field;
32433283
BOOL rc = FALSE;
32443284
rdpContext* context = update->context;
32453285
rdpPrimaryUpdate* primary = update->primary;
@@ -3263,8 +3303,11 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags)
32633303
if (!check_primary_order_supported(update->log, settings, orderInfo->orderType, orderName))
32643304
return FALSE;
32653305

3266-
if (!update_read_field_flags(s, &(orderInfo->fieldFlags), flags,
3267-
PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]))
3306+
field = get_primary_drawing_order_field_bytes(orderInfo->orderType, &rc);
3307+
if (!rc)
3308+
return FALSE;
3309+
3310+
if (!update_read_field_flags(s, &(orderInfo->fieldFlags), flags, field))
32683311
{
32693312
WLog_Print(update->log, WLOG_ERROR, "update_read_field_flags() failed");
32703313
return FALSE;

Diff for: libfreerdp/core/orders.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@
189189

190190
#define CG_GLYPH_UNICODE_PRESENT 0x0010
191191

192-
FREERDP_LOCAL extern const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[];
192+
FREERDP_LOCAL BYTE get_primary_drawing_order_field_bytes(UINT32 orderType, BOOL* pValid);
193193

194194
FREERDP_LOCAL BOOL update_recv_order(rdpUpdate* update, wStream* s);
195195

Diff for: libfreerdp/core/update.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,7 @@ static int update_prepare_order_info(rdpContext* context, ORDER_INFO* orderInfo,
10871087
orderInfo->controlFlags = ORDER_STANDARD;
10881088
orderInfo->controlFlags |= ORDER_TYPE_CHANGE;
10891089
length += 1;
1090-
length += PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType];
1090+
length += get_primary_drawing_order_field_bytes(orderInfo->orderType, NULL);
10911091
length += update_prepare_bounds(context, orderInfo);
10921092
return length;
10931093
}
@@ -1105,7 +1105,7 @@ static int update_write_order_info(rdpContext* context, wStream* s, ORDER_INFO*
11051105
Stream_Write_UINT8(s, orderInfo->orderType); /* orderType (1 byte) */
11061106

11071107
update_write_field_flags(s, orderInfo->fieldFlags, orderInfo->controlFlags,
1108-
PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]);
1108+
get_primary_drawing_order_field_bytes(orderInfo->orderType, NULL));
11091109
update_write_bounds(s, orderInfo);
11101110
Stream_SetPosition(s, position);
11111111
return 0;

0 commit comments

Comments
 (0)