[core,info] enforce cbClientDir limits
the cbClientDir field limits defined in [MS-RDPBCGR] 2.2.1.11.1.1.1
Extended Info Packet (TS_EXTENDED_INFO_PACKET) are now properly enforced.
@@ -459,6 +459,7 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s)
const size_t cbClientAddressMax = rdp_get_client_address_max_size(rdp);
WCHAR* clientDir = NULL;
size_t cbClientDir;
+ const size_t cbClientDirMax = 512;
UINT16 cbAutoReconnectCookie;
rdpSettings* settings;
if (!rdp || !rdp->settings || !s)
@@ -485,7 +486,17 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s)
clientDir = ConvertUtf8ToWCharAlloc(settings->ClientDir, &cbClientDir);
if (cbClientDir > (UINT16_MAX / sizeof(WCHAR)))
goto fail;
- cbClientDir = (UINT16)cbClientDir * sizeof(WCHAR);
+
+ cbClientDir = (UINT16)(cbClientDir + 1) * sizeof(WCHAR);
+ if (cbClientDir > cbClientDirMax)
+ {
+ WLog_WARN(
+ TAG, "[%s] the client dir %s [%" PRIuz "] exceeds the limit of %" PRIuz ", truncating.",
+ __FUNCTION__, settings->ClientDir, cbClientDir, cbClientDirMax);
+
+ clientDir[(cbClientDirMax / sizeof(WCHAR)) - 1] = '\0';
+ cbClientDir = cbClientDirMax;
+ }
if (settings->ServerAutoReconnectCookie->cbLen > UINT16_MAX)
goto fail;
@@ -496,11 +507,10 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s)
Stream_Write(s, clientAddress, cbClientAddress); /* clientAddress */
- Stream_Write_UINT16(s, cbClientDir + 2); /* cbClientDir (2 bytes) */
+ Stream_Write_UINT16(s, cbClientDir); /* cbClientDir (2 bytes) */
Stream_Write(s, clientDir, cbClientDir); /* clientDir */
- Stream_Write_UINT16(s, 0);
if (!rdp_write_client_time_zone(s, settings)) /* clientTimeZone (172 bytes) */
goto fail;
