Fixed freerdp_channel_process length checks
Fragmented data was not handled properly.
@@ -122,23 +122,46 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, const BYTE* data, int s
return TRUE;
}
-BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channelId)
+BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channelId, size_t packetLength)
{
+ int rc = 0;
UINT32 length;
UINT32 flags;
size_t chunkLength;
+ if (packetLength < 8)
+ {
+ WLog_ERR(TAG, "Header length %" PRIdz " bytes promised, none available", packetLength);
+ return FALSE;
+ }
+ packetLength -= 8;
+
if (Stream_GetRemainingLength(s) < 8)
return FALSE;
Stream_Read_UINT32(s, length);
Stream_Read_UINT32(s, flags);
chunkLength = Stream_GetRemainingLength(s);
- if (length > chunkLength)
+ if (packetLength != chunkLength)
+ {
+ WLog_ERR(TAG, "Header length %" PRIdz " != actual length %" PRIdz, packetLength,
+ chunkLength);
+ return FALSE;
+ }
+ if (length < chunkLength)
+ {
+ WLog_ERR(TAG, "Expected %" PRIu32 " bytes, but only have %" PRIdz, length, chunkLength);
return FALSE;
- IFCALL(instance->ReceiveChannelData, instance, channelId, Stream_Pointer(s), chunkLength, flags,
- length);
- return Stream_SafeSeek(s, length);
+ }
+ IFCALLRET(instance->ReceiveChannelData, rc, instance, channelId, Stream_Pointer(s), chunkLength,
+ flags, length);
+ if (rc != CHANNEL_RC_OK)
+ {
+ WLog_WARN(TAG, "ReceiveChannelData returned %d", rc);
+ return FALSE;
+ }
+
+ return Stream_SafeSeek(s, chunkLength);
}
BOOL freerdp_channel_peer_process(freerdp_peer* client, wStream* s, UINT16 channelId)
