Don't use NULL for pWrittenBytes when calling WTSVirtualChannelWrite()

Nothing in the MSDN API says that setting NULL is safe. And if the
implementation uses WriteFile directly, it crashes.
This commit is contained in:
Hardening 2014-05-28 17:04:24 +02:00
parent ea0a2a32ad
commit c076ffb020
6 changed files with 43 additions and 20 deletions

View File

@ -77,9 +77,11 @@ static void audin_server_select_format(audin_server_context* context, int client
static void audin_server_send_version(audin_server* audin, wStream* s)
{
ULONG written;
Stream_Write_UINT8(s, MSG_SNDIN_VERSION);
Stream_Write_UINT32(s, 1); /* Version (4 bytes) */
WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
}
static BOOL audin_server_recv_version(audin_server* audin, wStream* s, UINT32 length)
@ -101,6 +103,7 @@ static void audin_server_send_formats(audin_server* audin, wStream* s)
{
int i;
UINT32 nAvgBytesPerSec;
ULONG written;
Stream_SetPosition(s, 0);
Stream_Write_UINT8(s, MSG_SNDIN_FORMATS);
@ -131,7 +134,7 @@ static void audin_server_send_formats(audin_server* audin, wStream* s)
}
}
WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
}
static BOOL audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 length)
@ -181,6 +184,8 @@ static BOOL audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 le
static void audin_server_send_open(audin_server* audin, wStream* s)
{
ULONG written;
if (audin->context.selected_client_format < 0)
return;
@ -203,7 +208,7 @@ static void audin_server_send_open(audin_server* audin, wStream* s)
Stream_Write_UINT16(s, 16); /* wBitsPerSample */
Stream_Write_UINT16(s, 0); /* cbSize */
WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
}
static BOOL audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32 length)

View File

@ -68,6 +68,7 @@ static int cliprdr_server_send_capabilities(CliprdrServerContext* context)
BOOL status;
UINT32 generalFlags;
CLIPRDR_HEADER header;
ULONG written;
printf("CliprdrServerSendCapabilities\n");
@ -96,7 +97,7 @@ static int cliprdr_server_send_capabilities(CliprdrServerContext* context)
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
@ -108,6 +109,7 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context)
wStream* s;
BOOL status;
CLIPRDR_HEADER header;
ULONG written;
printf("CliprdrServerSendMonitorReady\n");
@ -123,7 +125,7 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context)
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
@ -135,6 +137,7 @@ static int cliprdr_server_send_format_list_response(CliprdrServerContext* contex
wStream* s;
BOOL status;
CLIPRDR_HEADER header;
ULONG written;
printf("CliprdrServerSendFormatListResponse\n");
@ -150,7 +153,7 @@ static int cliprdr_server_send_format_list_response(CliprdrServerContext* contex
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);

View File

@ -34,6 +34,7 @@ static int rdpdr_server_send_announce_request(RdpdrServerContext* context)
wStream* s;
BOOL status;
RDPDR_HEADER header;
ULONG written;
printf("RdpdrServerSendAnnounceRequest\n");
@ -51,7 +52,7 @@ static int rdpdr_server_send_announce_request(RdpdrServerContext* context)
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
@ -295,6 +296,7 @@ static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context
BOOL status;
RDPDR_HEADER header;
UINT16 numCapabilities;
ULONG written;
printf("RdpdrServerSendCoreCapabilityRequest\n");
@ -319,7 +321,7 @@ static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
@ -376,6 +378,7 @@ static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context)
wStream* s;
BOOL status;
RDPDR_HEADER header;
ULONG written;
printf("RdpdrServerSendClientIdConfirm\n");
@ -393,7 +396,7 @@ static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context)
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
@ -457,6 +460,7 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context)
wStream* s;
BOOL status;
RDPDR_HEADER header;
ULONG written;
printf("%s\n", __FUNCTION__);
@ -470,7 +474,7 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context)
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);

View File

@ -36,6 +36,7 @@ static BOOL rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
int pos;
UINT16 i;
BOOL status;
ULONG written;
Stream_Write_UINT8(s, SNDC_FORMATS);
Stream_Write_UINT8(s, 0);
@ -74,7 +75,7 @@ static BOOL rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
Stream_SetPosition(s, 2);
Stream_Write_UINT16(s, pos - 4);
Stream_SetPosition(s, pos);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_SetPosition(s, 0);
return status;
@ -360,6 +361,7 @@ static BOOL rdpsnd_server_send_audio_pdu(RdpsndServerContext* context)
BOOL status;
AUDIO_FORMAT* format;
int tbytes_per_frame;
ULONG written;
wStream* s = context->priv->rdpsnd_pdu;
format = &context->client_formats[context->selected_client_format];
@ -421,7 +423,7 @@ static BOOL rdpsnd_server_send_audio_pdu(RdpsndServerContext* context)
Stream_Seek(s, 3); /* bPad */
Stream_Write(s, src, 4);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
if (!status)
goto out;
Stream_SetPosition(s, 0);
@ -434,7 +436,7 @@ static BOOL rdpsnd_server_send_audio_pdu(RdpsndServerContext* context)
if (fill_size > 0)
Stream_Zero(s, fill_size);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
out:
Stream_SetPosition(s, 0);
@ -475,6 +477,7 @@ static BOOL rdpsnd_server_set_volume(RdpsndServerContext* context, int left, int
{
int pos;
BOOL status;
ULONG written;
wStream* s = context->priv->rdpsnd_pdu;
Stream_Write_UINT8(s, SNDC_SETVOLUME);
@ -488,7 +491,7 @@ static BOOL rdpsnd_server_set_volume(RdpsndServerContext* context, int left, int
Stream_SetPosition(s, 2);
Stream_Write_UINT16(s, pos - 4);
Stream_SetPosition(s, pos);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_SetPosition(s, 0);
return status;
@ -498,6 +501,7 @@ static BOOL rdpsnd_server_close(RdpsndServerContext* context)
{
int pos;
BOOL status;
ULONG written;
wStream* s = context->priv->rdpsnd_pdu;
if (context->selected_client_format < 0)
@ -519,7 +523,7 @@ static BOOL rdpsnd_server_close(RdpsndServerContext* context)
Stream_SetPosition(s, 2);
Stream_Write_UINT16(s, pos - 4);
Stream_SetPosition(s, pos);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_SetPosition(s, 0);
return status;

View File

@ -427,9 +427,11 @@ BOOL WTSVirtualChannelManagerCheckFileDescriptor(HANDLE hServer)
if (channel)
{
ULONG written;
vcm->drdynvc_channel = channel;
dynvc_caps = 0x00010050; /* DYNVC_CAPS_VERSION1 (4 bytes) */
WTSVirtualChannelWrite(channel, (PCHAR) &dynvc_caps, sizeof(dynvc_caps), NULL);
WTSVirtualChannelWrite(channel, (PCHAR) &dynvc_caps, sizeof(dynvc_caps), &written);
}
}
@ -916,6 +918,7 @@ HANDLE WINAPI FreeRDP_WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualNam
BOOL joined = FALSE;
freerdp_peer* client;
rdpPeerChannel* channel;
ULONG written;
WTSVirtualChannelManager* vcm;
if (SessionId == WTS_CURRENT_SESSION)
@ -968,7 +971,7 @@ HANDLE WINAPI FreeRDP_WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualNam
s = Stream_New(NULL, 64);
wts_write_drdynvc_create_request(s, channel->channelId, pVirtualName);
WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_Free(s, TRUE);
return channel;
@ -997,9 +1000,11 @@ BOOL WINAPI FreeRDP_WTSVirtualChannelClose(HANDLE hChannelHandle)
if (channel->dvc_open_state == DVC_OPEN_STATE_SUCCEEDED)
{
ULONG written;
s = Stream_New(NULL, 8);
wts_write_drdynvc_header(s, CLOSE_REQUEST_PDU, channel->channelId);
WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_Free(s, TRUE);
}
}

View File

@ -405,6 +405,7 @@ static void* tf_debug_channel_thread_func(void* arg)
wStream* s;
void* buffer;
DWORD BytesReturned = 0;
ULONG written;
testPeerContext* context = (testPeerContext*) arg;
if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &BytesReturned) == TRUE)
@ -417,7 +418,7 @@ static void* tf_debug_channel_thread_func(void* arg)
s = Stream_New(NULL, 4096);
WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test1", 5, NULL);
WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test1", 5, &written);
while (1)
{
@ -583,7 +584,8 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{
if (context->debug_channel)
{
WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test2", 5, NULL);
ULONG written;
WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test2", 5, &written);
}
}
else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */