From a13292237660142dd0cfaaf7d1f33174852774df Mon Sep 17 00:00:00 2001 From: David Fort Date: Mon, 2 Oct 2017 21:28:02 +0200 Subject: [PATCH] Add checks for DR channel --- channels/drive/client/drive_file.c | 19 ++++++++++++++++++- channels/drive/client/drive_main.c | 34 +++++++++++++++++++++++++++++----- libfreerdp/core/channels.c | 1 + libfreerdp/core/rdp.c | 2 ++ libfreerdp/core/security.c | 1 + libfreerdp/core/update.c | 4 ++++ 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index 1b11129..253b588 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -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!"); diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 6f3d54b..e100b19 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -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: diff --git a/libfreerdp/core/channels.c b/libfreerdp/core/channels.c index 63e720d..5a31611 100644 --- a/libfreerdp/core/channels.c +++ b/libfreerdp/core/channels.c @@ -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); diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index a76b2c4..8c7ce97 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -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: diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c index 807f58f..dc5526e 100644 --- a/libfreerdp/core/security.c +++ b/libfreerdp/core/security.c @@ -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)) diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 3c2b476..b0f2f90 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -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); -- 2.7.4