Add checks for DR channel
authorDavid Fort <contact@hardening-consulting.com>
Mon, 2 Oct 2017 19:28:02 +0000 (21:28 +0200)
committerDavid Fort <contact@hardening-consulting.com>
Wed, 4 Oct 2017 08:30:47 +0000 (10:30 +0200)
channels/drive/client/drive_file.c
channels/drive/client/drive_main.c
libfreerdp/core/channels.c
libfreerdp/core/rdp.c
libfreerdp/core/security.c
libfreerdp/core/update.c

index 1b11129..253b588 100644 (file)
@@ -561,6 +561,9 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
        switch (FsInformationClass)
        {
                case FileBasicInformation:
+                       if (Stream_GetRemainingLength(input) < 36)
+                               return FALSE;
+
                        /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
                        Stream_Read_UINT64(input, liCreationTime.QuadPart);
                        Stream_Read_UINT64(input, liLastAccessTime.QuadPart);
@@ -620,6 +623,9 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
 
                /* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
                case FileAllocationInformation:
+                       if (Stream_GetRemainingLength(input) < 8)
+                               return FALSE;
+
                        /* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
                        Stream_Read_INT64(input, size);
 
@@ -656,7 +662,12 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
                                break; /* TODO: SetLastError ??? */
 
                        if (Length)
+                       {
+                               if (Stream_GetRemainingLength(input) < 1)
+                                       return FALSE;
+
                                Stream_Read_UINT8(input, delete_pending);
+                       }
                        else
                                delete_pending = 1;
 
@@ -676,13 +687,19 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
                        break;
 
                case FileRenameInformation:
+                       if (Stream_GetRemainingLength(input) < 6)
+                               return FALSE;
+
                        /* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
                        Stream_Read_UINT8(input, ReplaceIfExists);
                        Stream_Seek_UINT8(input); /* RootDirectory */
                        Stream_Read_UINT32(input, FileNameLength);
+
+                       if (Stream_GetRemainingLength(input) < FileNameLength)
+                               return FALSE;
+
                        fullpath = drive_file_combine_fullpath(file->basepath, (WCHAR*)Stream_Pointer(input),
                                                               FileNameLength);
-
                        if (!fullpath)
                        {
                                WLog_ERR(TAG, "drive_file_combine_fullpath failed!");
index 6f3d54b..e100b19 100644 (file)
@@ -274,10 +274,13 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp)
        if (!drive || !irp || !irp->output || !irp->Complete)
                return ERROR_INVALID_PARAMETER;
 
+       if (Stream_GetRemainingLength(irp->input) < 12)
+               return ERROR_INVALID_DATA;
+
        Stream_Read_UINT32(irp->input, Length);
        Stream_Read_UINT64(irp->input, Offset);
-       file = drive_get_file_by_id(drive, irp->FileId);
 
+       file = drive_get_file_by_id(drive, irp->FileId);
        if (!file)
        {
                irp->IoStatus = STATUS_UNSUCCESSFUL;
@@ -328,11 +331,14 @@ static UINT drive_process_irp_write(DRIVE_DEVICE* drive, IRP* irp)
        if (!drive || !irp || !irp->input || !irp->output || !irp->Complete)
                return ERROR_INVALID_PARAMETER;
 
+       if (Stream_GetRemainingLength(irp->input) < 32)
+               return ERROR_INVALID_DATA;
+
        Stream_Read_UINT32(irp->input, Length);
        Stream_Read_UINT64(irp->input, Offset);
        Stream_Seek(irp->input, 20); /* Padding */
-       file = drive_get_file_by_id(drive, irp->FileId);
 
+       file = drive_get_file_by_id(drive, irp->FileId);
        if (!file)
        {
                irp->IoStatus = STATUS_UNSUCCESSFUL;
@@ -367,9 +373,12 @@ static UINT drive_process_irp_query_information(DRIVE_DEVICE* drive, IRP* irp)
        if (!drive || !irp || !irp->Complete)
                return ERROR_INVALID_PARAMETER;
 
+       if (Stream_GetRemainingLength(irp->input) < 4)
+               return ERROR_INVALID_DATA;
+
        Stream_Read_UINT32(irp->input, FsInformationClass);
-       file = drive_get_file_by_id(drive, irp->FileId);
 
+       file = drive_get_file_by_id(drive, irp->FileId);
        if (!file)
        {
                irp->IoStatus = STATUS_UNSUCCESSFUL;
@@ -396,11 +405,14 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp)
        if (!drive || !irp || !irp->Complete || !irp->input || !irp->output)
                return ERROR_INVALID_PARAMETER;
 
+       if (Stream_GetRemainingLength(irp->input) < 32)
+               return ERROR_INVALID_DATA;
+
        Stream_Read_UINT32(irp->input, FsInformationClass);
        Stream_Read_UINT32(irp->input, Length);
        Stream_Seek(irp->input, 24); /* Padding */
-       file = drive_get_file_by_id(drive, irp->FileId);
 
+       file = drive_get_file_by_id(drive, irp->FileId);
        if (!file)
        {
                irp->IoStatus = STATUS_UNSUCCESSFUL;
@@ -442,6 +454,9 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive,
        if (!drive || !irp)
                return ERROR_INVALID_PARAMETER;
 
+       if (Stream_GetRemainingLength(irp->input) < 4)
+               return ERROR_INVALID_DATA;
+
        Stream_Read_UINT32(irp->input, FsInformationClass);
        GetDiskFreeSpaceW(drive->path, &lpSectorsPerCluster, &lpBytesPerSector, &lpNumberOfFreeClusters,
                          &lpTotalNumberOfClusters);
@@ -574,7 +589,11 @@ static UINT drive_process_irp_silent_ignore(DRIVE_DEVICE* drive, IRP* irp)
        if (!drive || !irp || !irp->output || !irp->Complete)
                return ERROR_INVALID_PARAMETER;
 
+       if (Stream_GetRemainingLength(irp->input) < 4)
+               return ERROR_INVALID_DATA;
+
        Stream_Read_UINT32(irp->input, FsInformationClass);
+
        Stream_Write_UINT32(irp->output, 0); /* Length */
        return irp->Complete(irp);
 }
@@ -595,13 +614,16 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
        if (!drive || !irp || !irp->Complete)
                return ERROR_INVALID_PARAMETER;
 
+       if (Stream_GetRemainingLength(irp->input) < 32)
+               return ERROR_INVALID_DATA;
+
        Stream_Read_UINT32(irp->input, FsInformationClass);
        Stream_Read_UINT8(irp->input, InitialQuery);
        Stream_Read_UINT32(irp->input, PathLength);
        Stream_Seek(irp->input, 23); /* Padding */
        path = (WCHAR*) Stream_Pointer(irp->input);
-       file = drive_get_file_by_id(drive, irp->FileId);
 
+       file = drive_get_file_by_id(drive, irp->FileId);
        if (file == NULL)
        {
                irp->IoStatus = STATUS_UNSUCCESSFUL;
@@ -756,11 +778,13 @@ static void* drive_thread_func(void* arg)
                irp = (IRP*) message.wParam;
 
                if (irp)
+               {
                        if ((error = drive_process_irp(drive, irp)))
                        {
                                WLog_ERR(TAG, "drive_process_irp failed with error %"PRIu32"!", error);
                                break;
                        }
+               }
        }
 
 fail:
index 63e720d..5a31611 100644 (file)
@@ -110,6 +110,7 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, BYTE* data, int size)
 
                Stream_Write(s, data, chunkSize);
 
+               WLog_DBG(TAG, "%s: sending data (flags=0x%x size=%d)", __FUNCTION__, flags, size);
                if (!rdp_send(rdp, s, channelId))
                {
                        Stream_Release(s);
index a76b2c4..8c7ce97 100644 (file)
@@ -604,6 +604,7 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
        Stream_SetPosition(s, length);
        Stream_SealLength(s);
 
+       WLog_DBG(TAG, "%s: sending data (type=0x%x size=%d channelId)", __FUNCTION__, type, Stream_Length(s), channel_id);
        if (transport_write(rdp->transport, s) < 0)
                return FALSE;
 
@@ -1224,6 +1225,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
                                case PDU_TYPE_FLOW_RESPONSE:
                                case PDU_TYPE_FLOW_STOP:
                                case PDU_TYPE_FLOW_TEST:
+                                       WLog_DBG(TAG, "flow message 0x%04"PRIX16"", pduType);
                                        break;
 
                                default:
index 807f58f..dc5526e 100644 (file)
@@ -592,6 +592,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
        BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
        BOOL result = FALSE;
 
+       WLog_DBG(TAG, "updating RDP key");
        if (!(sha1 = winpr_Digest_New()))
                goto out;
        if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1))
index 3c2b476..b0f2f90 100644 (file)
@@ -562,6 +562,10 @@ BOOL update_recv(rdpUpdate* update, wStream* s)
                        update_read_synchronize(update, s);
                        IFCALL(update->Synchronize, context);
                        break;
+
+               default:
+                       WLog_ERR(TAG, "unknown update type %"PRIu16"", updateType);
+                       break;
        }
 
        IFCALL(update->EndPaint, context);