Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
freerdp.9501
freerdp-CVE-2018-1000852.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File freerdp-CVE-2018-1000852.patch of Package freerdp.9501
From baee520e3dd9be6511c45a14c5f5e77784de1471 Mon Sep 17 00:00:00 2001 From: Armin Novak <armin.novak@thincast.com> Date: Thu, 20 Sep 2018 09:06:01 +0200 Subject: [PATCH] Fix for #4866: Added additional length checks --- channels/drdynvc/client/drdynvc_main.c | 61 +++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) Index: b/channels/drdynvc/client/drdynvc_main.c =================================================================== --- a/channels/drdynvc/client/drdynvc_main.c 2019-01-10 17:03:57.153015287 +0800 +++ b/channels/drdynvc/client/drdynvc_main.c 2019-01-11 13:24:47.499539805 +0800 @@ -655,7 +655,7 @@ static UINT dvcman_receive_channel_data( if (channel->dvc_data) { /* Fragmented data */ - if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity(channel->dvc_data)) + if (Stream_GetPosition(channel->dvc_data) + dataSize > Stream_Capacity(channel->dvc_data)) { WLog_ERR(TAG, "data exceeding declared length!"); Stream_Release(channel->dvc_data); @@ -663,7 +663,7 @@ static UINT dvcman_receive_channel_data( return ERROR_INVALID_DATA; } - Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize); + Stream_Copy(data, channel->dvc_data, dataSize); if (((size_t) Stream_GetPosition(channel->dvc_data)) >= channel->dvc_data_length) { @@ -885,6 +885,9 @@ static UINT drdynvc_process_capability_r WLog_DBG(TAG, "capability_request Sp=%d cbChId=%d", Sp, cbChId); + if (Stream_GetRemainingLength(s) < 3) + return ERROR_INVALID_DATA; + Stream_Seek(s, 1); /* pad */ Stream_Read_UINT16(s, drdynvc->version); @@ -893,6 +896,9 @@ static UINT drdynvc_process_capability_r */ if ((drdynvc->version == 2) || (drdynvc->version == 3)) { + if (Stream_GetRemainingLength(s) < 8) + return ERROR_INVALID_DATA; + Stream_Read_UINT16(s, drdynvc->PriorityCharge0); Stream_Read_UINT16(s, drdynvc->PriorityCharge1); Stream_Read_UINT16(s, drdynvc->PriorityCharge2); @@ -906,6 +912,21 @@ static UINT drdynvc_process_capability_r return status; } +static UINT32 drdynvc_cblen_to_bytes(int cbLen) +{ + switch (cbLen) + { + case 0: + return 1; + + case 1: + return 2; + + default: + return 4; + } +} + static UINT32 drdynvc_read_variable_uint(wStream* s, int cbLen) { UINT32 val; @@ -941,6 +962,8 @@ static UINT drdynvc_process_create_reque UINT32 ChannelId; wStream* data_out; UINT channel_status; + char* name; + size_t length; if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES) { @@ -959,11 +982,20 @@ static UINT drdynvc_process_create_reque drdynvc->state = DRDYNVC_STATE_READY; } + if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId)) + return ERROR_INVALID_DATA; + ChannelId = drdynvc_read_variable_uint(s, cbChId); pos = Stream_GetPosition(s); - WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s)); + name = Stream_Pointer(s); + length = Stream_GetRemainingLength(s); + + if (strnlen(name, length) >= length) + return ERROR_INVALID_DATA; - channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s)); + WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, name); + + channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, name); data_out = Stream_New(NULL, pos + 4); @@ -1026,6 +1058,9 @@ static UINT drdynvc_process_data_first(d UINT32 Length; UINT32 ChannelId; + if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId) + drdynvc_cblen_to_bytes(Sp)) + return ERROR_INVALID_DATA; + ChannelId = drdynvc_read_variable_uint(s, cbChId); Length = drdynvc_read_variable_uint(s, Sp); WLog_DBG(TAG, "process_data_first: Sp=%d cbChId=%d, ChannelId=%d Length=%d", Sp, cbChId, ChannelId, Length); @@ -1047,6 +1082,9 @@ static UINT drdynvc_process_data(drdynvc { UINT32 ChannelId; + if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId)) + return ERROR_INVALID_DATA; + ChannelId = drdynvc_read_variable_uint(s, cbChId); WLog_DBG(TAG, "process_data: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId); @@ -1066,6 +1104,9 @@ static UINT drdynvc_process_close_reques UINT32 ChannelId; wStream* data_out; + if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId)) + return ERROR_INVALID_DATA; + ChannelId = drdynvc_read_variable_uint(s, cbChId); WLog_DBG(TAG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId); @@ -1110,6 +1151,9 @@ static UINT drdynvc_order_recv(drdynvcPl int Sp; int cbChId; + if (Stream_GetRemainingLength(s) < 1) + return ERROR_INVALID_DATA; + Stream_Read_UINT8(s, value); Cmd = (value & 0xf0) >> 4; @@ -1275,7 +1319,7 @@ static UINT drdynvc_virtual_channel_even return CHANNEL_RC_NO_MEMORY; } - if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) + if (!Stream_EnsureRemainingCapacity(data_in, dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); Stream_Free(drdynvc->data_in, TRUE);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor