diff --git a/libfreerdp-core/activation.c b/libfreerdp-core/activation.c index 5c781b8bf..de3b7f979 100644 --- a/libfreerdp-core/activation.c +++ b/libfreerdp-core/activation.c @@ -277,9 +277,16 @@ boolean rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s) { uint16 lengthSourceDescriptor; - stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ - stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ + /* + * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain + * the following fields. + */ + if (stream_get_left(s) > 0) + { + stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ + stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ + } rdp->state = CONNECTION_STATE_CAPABILITY; diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index c7bb01938..702fb9440 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -93,12 +93,17 @@ boolean rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, u { /* Share Control Header */ stream_read_uint16(s, *length); /* totalLength */ + + if (*length - 2 > stream_get_left(s)) + return false; + stream_read_uint16(s, *type); /* pduType */ - stream_read_uint16(s, *channel_id); /* pduSource */ *type &= 0x0F; /* type is in the 4 least significant bits */ - if (*length - 6 > stream_get_left(s)) - return false; + if (*length > 4) + stream_read_uint16(s, *channel_id); /* pduSource */ + else /* Windows XP can send such short DEACTIVATE_ALL PDUs. */ + *channel_id = 0; return true; } @@ -229,6 +234,9 @@ boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_ MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; mcs_read_domain_mcspdu_header(s, &MCSPDU, length); + if (*length - 8 > stream_get_left(s)) + return false; + per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, channel_id, 0); /* channelId */ stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */