Commit message: Fixed CVE-2018-8786

Thanks to Eyal Itkin from Check Point Software Technologies.
CVE: CVE-2018-8786
CWE: CWE-119
Vulnerability description: FreeRDP prior to version 2.0.0-rc4 contains an Integer Truncation that leads to a Heap-Based Buffer Overflow in function update_read_bitmap_update() and results in a memory corruption and probably even a remote code execution.

Project: FreeRDP
File: update.c

POINTER_CACHED_UPDATE* update_read_pointer_cached(rdpUpdate* update, wStream* s)
{
	POINTER_CACHED_UPDATE* pointer = calloc(1, sizeof(POINTER_CACHED_UPDATE));

	if (!pointer)
		goto fail;

	if (Stream_GetRemainingLength(s) < 2)
		goto fail;

	Stream_Read_UINT16(s, pointer->cacheIndex); /* cacheIndex (2 bytes) */
	return pointer;
fail:
	free_pointer_cached_update(update->context, pointer);
	return NULL;
}

Project: FreeRDP
File: update.c

static void 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.
	 */
}

Project: FreeRDP
File: update.c

static BOOL update_recv_orders(rdpUpdate* update, wStream* s)
{
	UINT16 numberOrders;

	if (Stream_GetRemainingLength(s) < 6)
	{
		WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 6");
		return FALSE;
	}

	Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */
	Stream_Read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */
	Stream_Seek_UINT16(s); /* pad2OctetsB (2 bytes) */

	while (numberOrders > 0)
	{
		if (!update_recv_order(update, s))
		{
			WLog_ERR(TAG, "update_recv_order() failed");
			return FALSE;
		}

		numberOrders--;
	}

	return TRUE;
}

Project: FreeRDP
File: update.c

static BOOL update_send_pointer_cached(rdpContext* context,
                                       const POINTER_CACHED_UPDATE* pointer_cached)
{
	wStream* s;
	rdpRdp* rdp = context->rdp;
	BOOL ret;
	s = fastpath_update_pdu_init(rdp->fastpath);

	if (!s)
		return FALSE;

	Stream_Write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
	ret = fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s,
	                               FALSE);
	Stream_Release(s);
	return ret;
}

Project: FreeRDP
File: update.c

static BOOL update_send_set_keyboard_ime_status(rdpContext* context,
        UINT16 imeId, UINT32 imeState, UINT32 imeConvMode)
{
	wStream* s;
	rdpRdp* rdp = context->rdp;
	s = rdp_data_pdu_init(rdp);

	if (!s)
		return FALSE;

	/* unitId should be 0 according to MS-RDPBCGR 2.2.8.2.2.1 */
	Stream_Write_UINT16(s, imeId);
	Stream_Write_UINT32(s, imeState);
	Stream_Write_UINT32(s, imeConvMode);
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS,
	                         rdp->mcs->userId);
}

Project: FreeRDP
File: update.c

static BOOL update_send_suppress_output(rdpContext* context, BYTE allow,
                                        const RECTANGLE_16* area)
{
	rdpRdp* rdp = context->rdp;

	if (rdp->settings->SuppressOutput)
	{
		wStream* s = rdp_data_pdu_init(rdp);

		if (!s)
			return FALSE;

		update_write_suppress_output(s, allow, area);
		return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT,
		                         rdp->mcs->userId);
	}

	return TRUE;
}

Project: FreeRDP
File: update.c

static BOOL update_send_synchronize(rdpContext* context)
{
	wStream* s;
	rdpRdp* rdp = context->rdp;
	BOOL ret;
	s = fastpath_update_pdu_init(rdp->fastpath);

	if (!s)
		return FALSE;

	Stream_Zero(s, 2); /* pad2Octets (2 bytes) */
	ret = fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE,
	                               s, FALSE);
	Stream_Release(s);
	return ret;
}