Fixed cliprdr_server_receive_capabilities

Thanks to hac425 CVE-2020-11017, CVE-2020-11018
This commit is contained in:
akallabeth 2020-04-15 16:41:52 +02:00
parent fd5bdee8b3
commit 8e1a1b4075

View File

@ -432,6 +432,9 @@ cliprdr_server_file_contents_response(CliprdrServerContext* context,
static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* context, wStream* s,
CLIPRDR_GENERAL_CAPABILITY_SET* cap_set)
{
if (Stream_GetRemainingLength(s) < 8)
return ERROR_INVALID_DATA;
Stream_Read_UINT32(s, cap_set->version); /* version (4 bytes) */
Stream_Read_UINT32(s, cap_set->generalFlags); /* generalFlags (4 bytes) */
@ -464,29 +467,33 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
UINT16 index;
UINT16 capabilitySetType;
UINT16 capabilitySetLength;
UINT error = CHANNEL_RC_OK;
UINT error = ERROR_INVALID_DATA;
size_t cap_sets_size = 0;
CLIPRDR_CAPABILITIES capabilities;
CLIPRDR_CAPABILITIES capabilities = { 0 };
CLIPRDR_CAPABILITY_SET* capSet;
void* tmp;
WINPR_UNUSED(header);
/* set `capabilitySets` to NULL so `realloc` will know to alloc the first block */
capabilities.capabilitySets = NULL;
WLog_DBG(TAG, "CliprdrClientCapabilities");
if (Stream_GetRemainingLength(s) < 4)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, capabilities.cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
Stream_Seek_UINT16(s); /* pad1 (2 bytes) */
for (index = 0; index < capabilities.cCapabilitiesSets; index++)
{
void* tmp = NULL;
if (Stream_GetRemainingLength(s) < 4)
goto out;
Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */
Stream_Read_UINT16(s, capabilitySetLength); /* capabilitySetLength (2 bytes) */
cap_sets_size += capabilitySetLength;
tmp = realloc(capabilities.capabilitySets, cap_sets_size);
if (cap_sets_size > 0)
tmp = realloc(capabilities.capabilitySets, cap_sets_size);
if (tmp == NULL)
{
WLog_ERR(TAG, "capabilities.capabilitySets realloc failed!");
@ -504,8 +511,9 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
switch (capSet->capabilitySetType)
{
case CB_CAPSTYPE_GENERAL:
if ((error = cliprdr_server_receive_general_capability(
context, s, (CLIPRDR_GENERAL_CAPABILITY_SET*)capSet)))
error = cliprdr_server_receive_general_capability(
context, s, (CLIPRDR_GENERAL_CAPABILITY_SET*)capSet);
if (error)
{
WLog_ERR(TAG,
"cliprdr_server_receive_general_capability failed with error %" PRIu32
@ -518,11 +526,11 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
default:
WLog_ERR(TAG, "unknown cliprdr capability set: %" PRIu16 "",
capSet->capabilitySetType);
error = ERROR_INVALID_DATA;
goto out;
}
}
error = CHANNEL_RC_OK;
IFCALLRET(context->ClientCapabilities, error, context, &capabilities);
out:
free(capabilities.capabilitySets);