From a5af2cc865b2fe0305beb8289110c6509dce6d26 Mon Sep 17 00:00:00 2001 From: David Fort Date: Thu, 23 Nov 2017 17:37:55 +0100 Subject: [PATCH] clipboard: add some checks for the message --- channels/cliprdr/client/cliprdr_main.c | 66 +++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 7dcd6bf..51d283c 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -34,6 +34,7 @@ #include "cliprdr_main.h" #include "cliprdr_format.h" +#ifdef WITH_DEBUG_CLIPRDR static const char* const CB_MSG_TYPE_STRINGS[] = { "", @@ -49,6 +50,7 @@ static const char* const CB_MSG_TYPE_STRINGS[] = "CB_LOCK_CLIPDATA", "CB_UNLOCK_CLIPDATA" }; +#endif CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr) { @@ -160,6 +162,9 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, return ERROR_INTERNAL_ERROR; } + if (Stream_GetRemainingLength(s) < 8) + return ERROR_INVALID_DATA; + Stream_Read_UINT32(s, version); /* version (4 bytes) */ Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ DEBUG_CLIPRDR("Version: %"PRIu32"", version); @@ -218,15 +223,25 @@ static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 cCapabilitiesSets; UINT16 capabilitySetType; UINT error = CHANNEL_RC_OK; + + if (Stream_GetRemainingLength(s) < 4) + return ERROR_INVALID_DATA; + Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ Stream_Seek_UINT16(s); /* pad1 (2 bytes) */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerCapabilities"); for (index = 0; index < cCapabilitiesSets; index++) { + if (Stream_GetRemainingLength(s) < 4) + return ERROR_INVALID_DATA; + Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */ Stream_Read_UINT16(s, lengthCapability); /* lengthCapability (2 bytes) */ + if (lengthCapability < 4 || Stream_GetRemainingLength(s) < lengthCapability-4) + return ERROR_INVALID_DATA; + switch (capabilitySetType) { case CB_CAPSTYPE_GENERAL: @@ -448,8 +463,7 @@ static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA; unlockClipboardData.msgFlags = flags; unlockClipboardData.dataLen = length; - Stream_Read_UINT32(s, - unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ + Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ IFCALLRET(context->ServerUnlockClipboardData, error, context, &unlockClipboardData); @@ -470,9 +484,17 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) UINT16 msgFlags; UINT32 dataLen; UINT error; + + if (Stream_GetRemainingLength(s) < 8) + return ERROR_INVALID_DATA; + Stream_Read_UINT16(s, msgType); /* msgType (2 bytes) */ Stream_Read_UINT16(s, msgFlags); /* msgFlags (2 bytes) */ Stream_Read_UINT32(s, dataLen); /* dataLen (4 bytes) */ + + if (Stream_GetRemainingLength(s) < dataLen) + return ERROR_INVALID_DATA; + #ifdef WITH_DEBUG_CLIPRDR WLog_DBG(TAG, "msgType: %s (%"PRIu16"), msgFlags: %"PRIu16" dataLen: %"PRIu32"", CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); @@ -500,40 +522,35 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) break; case CB_FORMAT_LIST_RESPONSE: - if ((error = cliprdr_process_format_list_response(cliprdr, s, dataLen, - msgFlags))) + if ((error = cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_format_list_response failed with error %"PRIu32"!", error); break; case CB_FORMAT_DATA_REQUEST: - if ((error = cliprdr_process_format_data_request(cliprdr, s, dataLen, - msgFlags))) + if ((error = cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_format_data_request failed with error %"PRIu32"!", error); break; case CB_FORMAT_DATA_RESPONSE: - if ((error = cliprdr_process_format_data_response(cliprdr, s, dataLen, - msgFlags))) + if ((error = cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_format_data_response failed with error %"PRIu32"!", error); break; case CB_FILECONTENTS_REQUEST: - if ((error = cliprdr_process_filecontents_request(cliprdr, s, dataLen, - msgFlags))) + if ((error = cliprdr_process_filecontents_request(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_filecontents_request failed with error %"PRIu32"!", error); break; case CB_FILECONTENTS_RESPONSE: - if ((error = cliprdr_process_filecontents_response(cliprdr, s, dataLen, - msgFlags))) + if ((error = cliprdr_process_filecontents_response(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_filecontents_response failed with error %"PRIu32"!", error); @@ -586,12 +603,9 @@ static UINT cliprdr_client_capabilities(CliprdrClientContext* context, Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */ Stream_Write_UINT16(s, 0); /* pad1 */ - generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) - capabilities->capabilitySets; - Stream_Write_UINT16(s, - generalCapabilitySet->capabilitySetType); /* capabilitySetType */ - Stream_Write_UINT16(s, - generalCapabilitySet->capabilitySetLength); /* lengthCapability */ + generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*)capabilities->capabilitySets; + Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetType); /* capabilitySetType */ + Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetLength); /* lengthCapability */ Stream_Write_UINT32(s, generalCapabilitySet->version); /* version */ Stream_Write_UINT32(s, generalCapabilitySet->generalFlags); /* generalFlags */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientCapabilities"); @@ -618,9 +632,7 @@ static UINT cliprdr_temp_directory(CliprdrClientContext* context, return ERROR_INTERNAL_ERROR; } - length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, - 0); - + length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, 0); if (length < 0) return ERROR_INTERNAL_ERROR; @@ -796,8 +808,7 @@ static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, - lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ + Stream_Write_UINT32(s, lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientLockClipboardData: clipDataId: 0x%08"PRIX32"", lockClipboardData->clipDataId); @@ -822,8 +833,7 @@ static UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, - unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ + Stream_Write_UINT32(s, unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientUnlockClipboardData: clipDataId: 0x%08"PRIX32"", unlockClipboardData->clipDataId); @@ -852,8 +862,7 @@ static UINT cliprdr_client_format_data_request(CliprdrClientContext* context, return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, - formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ + Stream_Write_UINT32(s, formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataRequest"); return cliprdr_packet_send(cliprdr, s); } @@ -1202,8 +1211,7 @@ static VOID VCAPITYPE cliprdr_virtual_channel_init_event_ex(LPVOID lpUserParam, switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = cliprdr_virtual_channel_event_connected(cliprdr, pData, - dataLength))) + if ((error = cliprdr_virtual_channel_event_connected(cliprdr, pData, dataLength))) WLog_ERR(TAG, "cliprdr_virtual_channel_event_connected failed with error %"PRIu32"!", error); -- 2.7.4