In FreeRDP after 1.1 and before 2.0.0, a stream out-of-bounds seek in rdp_read_font_capability_set could lead to a later out-of-bounds read. As a result, a manipulated client or server might force a disconnect due to an invalid data read. This has been fixed in 2.0.0.
cpe:2.3:a:freerdp:freerdp:*:*:*:*:*:*:*:*
5D51A2C7-56AC-4CD2-B6AC-560C3B166209
2.0.0
1.1.0
OR
cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:lts:*:*:*
F7016A2A-8365-4F1A-89A2-7A19F2BCAE5B
cpe:2.3:o:canonical:ubuntu_linux:18.04:*:*:*:esm:*:*:*
B3293E55-5506-4587-A318-D1734F781C09
cpe:2.3:o:canonical:ubuntu_linux:19.10:*:*:*:*:*:*:*
A31C8344-3E02-4EB8-8BD8-4C84B7959624
cpe:2.3:o:canonical:ubuntu_linux:20.04:*:*:*:lts:*:*:*
902B8056-9E37-443B-8905-8AA93E2447FB
OR
cpe:2.3:o:debian:debian_linux:9.0:*:*:*:*:*:*:*
DEECE5FC-CACF-4496-A3E7-164736409252
cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*
07B237A9-69A3-4A9C-9DA0-4E06BD37AE73
OR
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.
















stream out of bounds seek in rdp_read_font_capability_set could lead out of bounds read later
This is a GitHub Issue
repo:FreeRDP
owner:FreeRDP
Title : stream out of bounds seek in rdp_read_font_capability_set could lead out of bounds read later
Issue date:

--- start body ---
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.
















--- end body ---

comments :
--- start comments ---

--- end comments ---