Merge pull request #3079 from akallabeth/drive_hotplug_fix

Fixed argument checks for drive channel.
This commit is contained in:
Hardening 2016-02-04 09:06:43 +01:00
commit 13df05be78
6 changed files with 324 additions and 194 deletions

View File

@ -6,6 +6,7 @@
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH * Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com> * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -42,6 +43,9 @@
void devman_device_free(DEVICE* device) void devman_device_free(DEVICE* device)
{ {
if (!device)
return;
IFCALL(device->Free, device); IFCALL(device->Free, device);
} }
@ -49,6 +53,9 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
{ {
DEVMAN* devman; DEVMAN* devman;
if (!rdpdr)
return NULL;
devman = (DEVMAN*) calloc(1, sizeof(DEVMAN)); devman = (DEVMAN*) calloc(1, sizeof(DEVMAN));
if (!devman) if (!devman)
@ -84,6 +91,9 @@ void devman_unregister_device(DEVMAN* devman, void* key)
{ {
DEVICE* device; DEVICE* device;
if (!devman || !key)
return;
device = (DEVICE*) ListDictionary_Remove(devman->devices, key); device = (DEVICE*) ListDictionary_Remove(devman->devices, key);
if (device) if (device)
@ -99,6 +109,12 @@ static UINT devman_register_device(DEVMAN* devman, DEVICE* device)
{ {
void* key = NULL; void* key = NULL;
if (!devman || !device)
return ERROR_INVALID_PARAMETER;
if (device->type != RDPDR_DTYP_FILESYSTEM)
return CHANNEL_RC_OK;
device->id = devman->id_sequence++; device->id = devman->id_sequence++;
key = (void*) (size_t) device->id; key = (void*) (size_t) device->id;
@ -115,6 +131,9 @@ DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
DEVICE* device = NULL; DEVICE* device = NULL;
void* key = (void*) (size_t) id; void* key = (void*) (size_t) id;
if (!devman)
return NULL;
device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key); device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key);
return device; return device;
@ -137,6 +156,9 @@ UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext
DEVICE_SERVICE_ENTRY_POINTS ep; DEVICE_SERVICE_ENTRY_POINTS ep;
PDEVICE_SERVICE_ENTRY entry = NULL; PDEVICE_SERVICE_ENTRY entry = NULL;
if (!devman || !device || !rdpcontext)
return ERROR_INVALID_PARAMETER;
if (device->Type == RDPDR_DTYP_FILESYSTEM) if (device->Type == RDPDR_DTYP_FILESYSTEM)
ServiceName = DRIVE_SERVICE_NAME; ServiceName = DRIVE_SERVICE_NAME;
else if (device->Type == RDPDR_DTYP_PRINT) else if (device->Type == RDPDR_DTYP_PRINT)

View File

@ -77,18 +77,28 @@ static UINT irp_complete(IRP* irp)
return error; return error;
} }
IRP* irp_new(DEVMAN* devman, wStream* s) IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
{ {
IRP* irp; IRP* irp;
DEVICE* device; DEVICE* device;
UINT32 DeviceId; UINT32 DeviceId;
if (Stream_GetRemainingLength(s) < 20)
{
if (error)
*error = ERROR_INVALID_DATA;
return NULL;
}
Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */ Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
device = devman_get_device_by_id(devman, DeviceId); device = devman_get_device_by_id(devman, DeviceId);
if (!device) if (!device)
{ {
WLog_ERR(TAG, "devman_get_device_by_id failed!"); WLog_WARN(TAG, "devman_get_device_by_id failed!");
if (error)
*error = CHANNEL_RC_OK;
return NULL; return NULL;
}; };
@ -97,6 +107,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
if (!irp) if (!irp)
{ {
WLog_ERR(TAG, "_aligned_malloc failed!"); WLog_ERR(TAG, "_aligned_malloc failed!");
if (error)
*error = CHANNEL_RC_NO_MEMORY;
return NULL; return NULL;
} }
@ -117,6 +129,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
{ {
WLog_ERR(TAG, "Stream_New failed!"); WLog_ERR(TAG, "Stream_New failed!");
_aligned_free(irp); _aligned_free(irp);
if (error)
*error = CHANNEL_RC_NO_MEMORY;
return NULL; return NULL;
} }
Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); /* Component (2 bytes) */ Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); /* Component (2 bytes) */
@ -131,5 +145,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
irp->thread = NULL; irp->thread = NULL;
irp->cancelled = FALSE; irp->cancelled = FALSE;
if (error)
*error = CHANNEL_RC_OK;
return irp; return irp;
} }

View File

@ -23,6 +23,6 @@
#include "rdpdr_main.h" #include "rdpdr_main.h"
IRP* irp_new(DEVMAN* devman, wStream* s); IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error);
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H */ #endif /* FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H */

View File

@ -4,8 +4,9 @@
* *
* Copyright 2010-2011 Vic Lee * Copyright 2010-2011 Vic Lee
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH * Copyright 2015-2016 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com> * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -60,12 +61,21 @@ static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s)
} }
/* Process device direction general capability set */ /* Process device direction general capability set */
static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s) static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
{ {
UINT16 capabilityLength; UINT16 capabilityLength;
if (Stream_GetRemainingLength(s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, capabilityLength); Stream_Read_UINT16(s, capabilityLength);
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
return ERROR_INVALID_DATA;
Stream_Seek(s, capabilityLength - 4); Stream_Seek(s, capabilityLength - 4);
return CHANNEL_RC_OK;
} }
/* Output printer direction capability set */ /* Output printer direction capability set */
@ -75,12 +85,21 @@ static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
} }
/* Process printer direction capability set */ /* Process printer direction capability set */
static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s) static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
{ {
UINT16 capabilityLength; UINT16 capabilityLength;
if (Stream_GetRemainingLength(s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, capabilityLength); Stream_Read_UINT16(s, capabilityLength);
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
return ERROR_INVALID_DATA;
Stream_Seek(s, capabilityLength - 4); Stream_Seek(s, capabilityLength - 4);
return CHANNEL_RC_OK;
} }
/* Output port redirection capability set */ /* Output port redirection capability set */
@ -90,12 +109,21 @@ static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, wStream* s)
} }
/* Process port redirection capability set */ /* Process port redirection capability set */
static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s) static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
{ {
UINT16 capabilityLength; UINT16 capabilityLength;
if (Stream_GetRemainingLength(s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, capabilityLength); Stream_Read_UINT16(s, capabilityLength);
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
return ERROR_INVALID_DATA;
Stream_Seek(s, capabilityLength - 4); Stream_Seek(s, capabilityLength - 4);
return CHANNEL_RC_OK;
} }
/* Output drive redirection capability set */ /* Output drive redirection capability set */
@ -105,12 +133,21 @@ static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
} }
/* Process drive redirection capability set */ /* Process drive redirection capability set */
static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s) static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
{ {
UINT16 capabilityLength; UINT16 capabilityLength;
if (Stream_GetRemainingLength(s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, capabilityLength); Stream_Read_UINT16(s, capabilityLength);
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
return ERROR_INVALID_DATA;
Stream_Seek(s, capabilityLength - 4); Stream_Seek(s, capabilityLength - 4);
return CHANNEL_RC_OK;
} }
/* Output smart card redirection capability set */ /* Output smart card redirection capability set */
@ -120,53 +157,77 @@ static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
} }
/* Process smartcard redirection capability set */ /* Process smartcard redirection capability set */
static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s) static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
{ {
UINT16 capabilityLength; UINT16 capabilityLength;
if (Stream_GetRemainingLength(s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, capabilityLength); Stream_Read_UINT16(s, capabilityLength);
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
return ERROR_INVALID_DATA;
Stream_Seek(s, capabilityLength - 4); Stream_Seek(s, capabilityLength - 4);
return CHANNEL_RC_OK;
} }
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
{ {
UINT status = CHANNEL_RC_OK;
UINT16 i; UINT16 i;
UINT16 numCapabilities; UINT16 numCapabilities;
UINT16 capabilityType; UINT16 capabilityType;
if (!rdpdr || !s)
return CHANNEL_RC_NULL_DATA;
if (Stream_GetRemainingLength(s) < 4)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, numCapabilities); Stream_Read_UINT16(s, numCapabilities);
Stream_Seek(s, 2); /* pad (2 bytes) */ Stream_Seek(s, 2); /* pad (2 bytes) */
for (i = 0; i < numCapabilities; i++) for (i = 0; i < numCapabilities; i++)
{ {
if (Stream_GetRemainingLength(s) < sizeof(UINT16))
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, capabilityType); Stream_Read_UINT16(s, capabilityType);
switch (capabilityType) switch (capabilityType)
{ {
case CAP_GENERAL_TYPE: case CAP_GENERAL_TYPE:
rdpdr_process_general_capset(rdpdr, s); status = rdpdr_process_general_capset(rdpdr, s);
break; break;
case CAP_PRINTER_TYPE: case CAP_PRINTER_TYPE:
rdpdr_process_printer_capset(rdpdr, s); status = rdpdr_process_printer_capset(rdpdr, s);
break; break;
case CAP_PORT_TYPE: case CAP_PORT_TYPE:
rdpdr_process_port_capset(rdpdr, s); status = rdpdr_process_port_capset(rdpdr, s);
break; break;
case CAP_DRIVE_TYPE: case CAP_DRIVE_TYPE:
rdpdr_process_drive_capset(rdpdr, s); status = rdpdr_process_drive_capset(rdpdr, s);
break; break;
case CAP_SMARTCARD_TYPE: case CAP_SMARTCARD_TYPE:
rdpdr_process_smartcard_capset(rdpdr, s); status = rdpdr_process_smartcard_capset(rdpdr, s);
break; break;
default: default:
break; break;
} }
if (status != CHANNEL_RC_OK)
return status;
} }
return CHANNEL_RC_OK;
} }
/** /**

View File

@ -25,7 +25,7 @@
#include "rdpdr_main.h" #include "rdpdr_main.h"
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s); UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s);
UINT rdpdr_send_capability_response(rdpdrPlugin* rdpdr); UINT rdpdr_send_capability_response(rdpdrPlugin* rdpdr);
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_CAPABILITIES_H */ #endif /* FREERDP_CHANNEL_RDPDR_CLIENT_CAPABILITIES_H */

View File

@ -4,8 +4,9 @@
* *
* Copyright 2010-2011 Vic Lee * Copyright 2010-2011 Vic Lee
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH * Copyright 2015-2016 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com> * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -81,7 +82,7 @@ static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 cou
UINT32 i; UINT32 i;
wStream* s; wStream* s;
s = Stream_New(NULL, 256); s = Stream_New(NULL, count * sizeof(UINT32) + 8);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "Stream_New failed!"); WLog_ERR(TAG, "Stream_New failed!");
@ -429,7 +430,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
BOOL dev_found = FALSE; BOOL dev_found = FALSE;
device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]); device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]);
if (!device_ext) if (!device_ext || !device_ext->path)
continue; continue;
/* not plugable device */ /* not plugable device */
@ -496,7 +497,6 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
free(drive->Path); free(drive->Path);
free(drive->Name); free(drive->Name);
free(drive); free(drive);
error = CHANNEL_RC_NO_MEMORY;
goto cleanup; goto cleanup;
} }
} }
@ -592,6 +592,7 @@ out:
static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
{ {
UINT error; UINT error;
if (rdpdr->hotplugThread) if (rdpdr->hotplugThread)
{ {
if (rdpdr->stopEvent) if (rdpdr->stopEvent)
@ -661,13 +662,18 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
return error; return error;
} }
static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s) static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s)
{ {
if (Stream_GetRemainingLength(s) < 8)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, rdpdr->versionMajor); Stream_Read_UINT16(s, rdpdr->versionMajor);
Stream_Read_UINT16(s, rdpdr->versionMinor); Stream_Read_UINT16(s, rdpdr->versionMinor);
Stream_Read_UINT32(s, rdpdr->clientID); Stream_Read_UINT32(s, rdpdr->clientID);
rdpdr->sequenceId++; rdpdr->sequenceId++;
return CHANNEL_RC_OK;
} }
/** /**
@ -683,7 +689,7 @@ static UINT rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
if (!s) if (!s)
{ {
WLog_ERR(TAG, "Stream_New failed!"); WLog_ERR(TAG, "Stream_New failed!");
return CHANNEL_RC_OK; return CHANNEL_RC_NO_MEMORY;
} }
Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */ Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */
@ -733,12 +739,15 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
return rdpdr_send(rdpdr, s); return rdpdr_send(rdpdr, s);
} }
static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s) static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s)
{ {
UINT16 versionMajor; UINT16 versionMajor;
UINT16 versionMinor; UINT16 versionMinor;
UINT32 clientID; UINT32 clientID;
if (Stream_GetRemainingLength(s) < 8)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, versionMajor); Stream_Read_UINT16(s, versionMajor);
Stream_Read_UINT16(s, versionMinor); Stream_Read_UINT16(s, versionMinor);
Stream_Read_UINT32(s, clientID); Stream_Read_UINT32(s, clientID);
@ -750,9 +759,9 @@ static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s
} }
if (clientID != rdpdr->clientID) if (clientID != rdpdr->clientID)
{
rdpdr->clientID = clientID; rdpdr->clientID = clientID;
}
return CHANNEL_RC_OK;
} }
/** /**
@ -810,7 +819,7 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
if (!Stream_EnsureRemainingCapacity(s, 20 + data_len)) if (!Stream_EnsureRemainingCapacity(s, 20 + data_len))
{ {
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY; return ERROR_INVALID_DATA;
} }
Stream_Write_UINT32(s, device->type); /* deviceType */ Stream_Write_UINT32(s, device->type); /* deviceType */
@ -859,12 +868,12 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
IRP* irp; IRP* irp;
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
irp = irp_new(rdpdr->devman, s); irp = irp_new(rdpdr->devman, s, &error);
if (!irp) if (!irp)
{ {
WLog_ERR(TAG, "irp_new failed!"); WLog_ERR(TAG, "irp_new failed with %lu!", error);
return CHANNEL_RC_NO_MEMORY; return error;
} }
IFCALLRET(irp->device->IRPRequest, error, irp->device, irp); IFCALLRET(irp->device->IRPRequest, error, irp->device, irp);
@ -921,6 +930,12 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
UINT32 status; UINT32 status;
UINT error; UINT error;
if (!rdpdr || !s)
return CHANNEL_RC_NULL_DATA;
if (Stream_GetRemainingLength(s) < 4)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, component); /* Component (2 bytes) */ Stream_Read_UINT16(s, component); /* Component (2 bytes) */
Stream_Read_UINT16(s, packetId); /* PacketId (2 bytes) */ Stream_Read_UINT16(s, packetId); /* PacketId (2 bytes) */
@ -929,7 +944,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
switch (packetId) switch (packetId)
{ {
case PAKID_CORE_SERVER_ANNOUNCE: case PAKID_CORE_SERVER_ANNOUNCE:
rdpdr_process_server_announce_request(rdpdr, s); if ((error = rdpdr_process_server_announce_request(rdpdr, s)))
return error;
if ((error = rdpdr_send_client_announce_reply(rdpdr))) if ((error = rdpdr_send_client_announce_reply(rdpdr)))
{ {
WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error); WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error);
@ -948,7 +964,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
break; break;
case PAKID_CORE_SERVER_CAPABILITY: case PAKID_CORE_SERVER_CAPABILITY:
rdpdr_process_capability_request(rdpdr, s); if ((error = rdpdr_process_capability_request(rdpdr, s)))
return error;
if ((error = rdpdr_send_capability_response(rdpdr))) if ((error = rdpdr_send_capability_response(rdpdr)))
{ {
WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error); WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error);
@ -957,7 +974,9 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
break; break;
case PAKID_CORE_CLIENTID_CONFIRM: case PAKID_CORE_CLIENTID_CONFIRM:
rdpdr_process_server_clientid_confirm(rdpdr, s); if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s)))
return error;
if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE))) if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
{ {
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error); WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
@ -975,6 +994,9 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
case PAKID_CORE_DEVICE_REPLY: case PAKID_CORE_DEVICE_REPLY:
/* connect to a specific resource */ /* connect to a specific resource */
if (Stream_GetRemainingLength(s) < 8)
return ERROR_INVALID_DATA;
Stream_Read_UINT32(s, deviceId); Stream_Read_UINT32(s, deviceId);
Stream_Read_UINT32(s, status); Stream_Read_UINT32(s, status);
break; break;
@ -1002,6 +1024,9 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
case PAKID_PRN_CACHE_DATA: case PAKID_PRN_CACHE_DATA:
{ {
UINT32 eventID; UINT32 eventID;
if (Stream_GetRemainingLength(s) < 4)
return ERROR_INVALID_DATA;
Stream_Read_UINT32(s, eventID); Stream_Read_UINT32(s, eventID);
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID); WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID);
} }
@ -1132,10 +1157,11 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
UINT status; UINT status;
rdpdrPlugin* plugin = (rdpdrPlugin*) rdpdr; rdpdrPlugin* plugin = (rdpdrPlugin*) rdpdr;
if (!rdpdr || !s)
return CHANNEL_RC_NULL_DATA;
if (!plugin) if (!plugin)
{
status = CHANNEL_RC_BAD_INIT_HANDLE; status = CHANNEL_RC_BAD_INIT_HANDLE;
}
else else
{ {
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle,
@ -1190,7 +1216,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
{ {
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY; return ERROR_INVALID_DATA;
} }
Stream_Write(data_in, pData, dataLength); Stream_Write(data_in, pData, dataLength);
@ -1223,7 +1249,7 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT ev
rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle); rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle);
if (!rdpdr) if (!rdpdr || !pData)
{ {
WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match"); WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match");
return; return;
@ -1256,6 +1282,12 @@ static void* rdpdr_virtual_channel_client_thread(void* arg)
rdpdrPlugin* rdpdr = (rdpdrPlugin*) arg; rdpdrPlugin* rdpdr = (rdpdrPlugin*) arg;
UINT error; UINT error;
if (!rdpdr)
{
ExitThread((DWORD) CHANNEL_RC_NULL_DATA);
return NULL;
}
if ((error = rdpdr_process_connect(rdpdr))) if ((error = rdpdr_process_connect(rdpdr)))
{ {
WLog_ERR(TAG, "rdpdr_process_connect failed with error %lu!", error); WLog_ERR(TAG, "rdpdr_process_connect failed with error %lu!", error);
@ -1444,7 +1476,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
rdpdrPlugin* rdpdr; rdpdrPlugin* rdpdr;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin)); rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin));
if (!rdpdr) if (!rdpdr)
@ -1473,7 +1504,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
rc = rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle, rc = rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle,
&rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event); &rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event);