Skip to content

Commit

Permalink
Fixed invalid access in update_recv_primary_order
Browse files Browse the repository at this point in the history
CVE-2020-11095 thanks @antonio-morales for finding this.
  • Loading branch information
akallabeth committed Jun 22, 2020
1 parent c3a1ed7 commit 733ee32
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 35 deletions.
107 changes: 75 additions & 32 deletions libfreerdp/core/orders.c
Expand Up @@ -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 };

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion libfreerdp/core/orders.h
Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions libfreerdp/core/update.c
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down

0 comments on commit 733ee32

Please sign in to comment.