[core,info] enforce extended info limits
the cbClientAddress field limits defined in [MS-RDPBCGR] 2.2.1.11.1.1.1 Extended Info Packet (TS_EXTENDED_INFO_PACKET) are now properly enforced.
This commit is contained in:
parent
4ab9fb4425
commit
0da0f5ca54
@ -274,6 +274,27 @@ static void rdp_write_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s)
|
||||
Stream_Write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier (16 bytes) */
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the cbClientAddress size limit
|
||||
* see [MS-RDPBCGR] 2.2.1.11.1.1.1 Extended Info Packet (TS_EXTENDED_INFO_PACKET)
|
||||
*/
|
||||
|
||||
static size_t rdp_get_client_address_max_size(const rdpRdp* rdp)
|
||||
{
|
||||
UINT32 version;
|
||||
rdpSettings* settings;
|
||||
|
||||
WINPR_ASSERT(rdp);
|
||||
|
||||
settings = rdp->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
version = freerdp_settings_get_uint32(settings, FreeRDP_RdpVersion);
|
||||
if (version < RDP_VERSION_10_0)
|
||||
return 64;
|
||||
return 80;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Extended Info Packet (TS_EXTENDED_INFO_PACKET).
|
||||
* msdn{cc240476}
|
||||
@ -300,7 +321,7 @@ static BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s)
|
||||
* is mandatory, connections via Microsoft's TS Gateway set cbClientAddress to 0.
|
||||
*/
|
||||
|
||||
if ((cbClientAddress % 2) || cbClientAddress > 80)
|
||||
if ((cbClientAddress % 2) || (cbClientAddress > rdp_get_client_address_max_size(rdp)))
|
||||
{
|
||||
WLog_ERR(TAG, "protocol error: invalid cbClientAddress value: %" PRIu16 "",
|
||||
cbClientAddress);
|
||||
@ -435,6 +456,7 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s)
|
||||
UINT16 clientAddressFamily;
|
||||
WCHAR* clientAddress = NULL;
|
||||
size_t cbClientAddress;
|
||||
const size_t cbClientAddressMax = rdp_get_client_address_max_size(rdp);
|
||||
WCHAR* clientDir = NULL;
|
||||
size_t cbClientDir;
|
||||
UINT16 cbAutoReconnectCookie;
|
||||
@ -447,7 +469,18 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (cbClientAddress > (UINT16_MAX / sizeof(WCHAR)))
|
||||
goto fail;
|
||||
cbClientAddress = (UINT16)cbClientAddress * sizeof(WCHAR);
|
||||
|
||||
cbClientAddress = (UINT16)(cbClientAddress + 1) * sizeof(WCHAR);
|
||||
if (cbClientAddress > cbClientAddressMax)
|
||||
{
|
||||
WLog_WARN(TAG,
|
||||
"[%s] the client address %s [%" PRIuz "] exceeds the limit of %" PRIuz
|
||||
", truncating.",
|
||||
__FUNCTION__, settings->ClientAddress, cbClientAddress, cbClientAddressMax);
|
||||
|
||||
clientAddress[(cbClientAddressMax / sizeof(WCHAR)) - 1] = '\0';
|
||||
cbClientAddress = cbClientAddressMax;
|
||||
}
|
||||
|
||||
clientDir = ConvertUtf8ToWCharAlloc(settings->ClientDir, &cbClientDir);
|
||||
if (cbClientDir > (UINT16_MAX / sizeof(WCHAR)))
|
||||
@ -459,11 +492,10 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s)
|
||||
cbAutoReconnectCookie = (UINT16)settings->ServerAutoReconnectCookie->cbLen;
|
||||
|
||||
Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */
|
||||
Stream_Write_UINT16(s, cbClientAddress + 2); /* cbClientAddress (2 bytes) */
|
||||
Stream_Write_UINT16(s, cbClientAddress); /* cbClientAddress (2 bytes) */
|
||||
|
||||
Stream_Write(s, clientAddress, cbClientAddress); /* clientAddress */
|
||||
|
||||
Stream_Write_UINT16(s, 0);
|
||||
Stream_Write_UINT16(s, cbClientDir + 2); /* cbClientDir (2 bytes) */
|
||||
|
||||
Stream_Write(s, clientDir, cbClientDir); /* clientDir */
|
||||
|
Loading…
Reference in New Issue
Block a user