clipboard: add some checks for the message
authorDavid Fort <contact@hardening-consulting.com>
Thu, 23 Nov 2017 16:37:55 +0000 (17:37 +0100)
committerDavid Fort <contact@hardening-consulting.com>
Thu, 23 Nov 2017 16:37:55 +0000 (17:37 +0100)
channels/cliprdr/client/cliprdr_main.c

index 7dcd6bf..51d283c 100644 (file)
@@ -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);