Closed
Description
version
https://github.com/FreeRDP/FreeRDP/blob/9ef1e81c559bb19d613b4da2d68908ea5d7f9259/libfreerdp/core/capabilities.c#L1398
vuln code
rdp_read_capability_sets first read 2 byte to length, then check Stream_GetRemainingLength(s) + 4 < length
assume Stream_GetRemainingLength(s)=1 and length=5, then the program will pass the check and continue execution
static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCapabilities,
UINT16 totalLength)
{
// read length from s
rdp_read_capability_set_header(s, &length, &type);
if (Stream_GetRemainingLength(s) + 4 < ((size_t)length))
{
WLog_ERR(TAG, "error processing stream");
return FALSE;
}
we could control type=CAPSET_TYPE_FONT, then it could enter rdp_read_font_capability_set
case CAPSET_TYPE_FONT:
if (!rdp_read_font_capability_set(s, length, settings))
return FALSE;
break;
rdp_read_font_capability_set could call Stream_Seek_UINT16(s), because length=5
But currently Stream_GetRemainingLength(s)=1
static BOOL rdp_read_font_capability_set(wStream* s, UINT16 length, rdpSettings* settings)
{
if (length > 4)
Stream_Seek_UINT16(s); /* fontSupportFlags (2 bytes) */
if (length > 6)
Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */
return TRUE;
}
After Stream_Seek_UINT16 done, it could lead _s->pointer - _s->buffer > _s->length
Then the check in other functions could fail, and could lead out of bounds read later.