Summary

An out-of-bounds (OOB) read vulnerability has been detected in RLEDECOMPRESS due to an incorrect range checking in pbSrc.

Product

FreeRDP

Tested Version

Development version - master branch (Jun 01, 2020)

Details: Out-of-bound read in RLEDECOMPRESS

The RLEDECOMPRESS function in codec\include\bitmap.c performs a call to SRCREADPIXEL(pixelA, pbSrc) (line 255), where SRCREADPIXEL is a macro that assigns the value pointed to by pbSrc to pixelA variable:

View on GitHub!

/* libfreerdp/codec/interleaved.c */
...
#define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0]
...

pbSrc is a pointer acting as an iterator which points to the next unread byte in the pbSrcBuffer array:

View on GitHub!

/* libfreerdp/codec/interleaved.c */
...
const BYTE* pbSrc = pbSrcBuffer;
const BYTE* pbEnd;
...
while (pbSrc < pbEnd)
{
...

Also, pbEnd points to the last element of pbsrcBuffer. And while (pbSrc < pbEnd) is the loop which iterates through the pbSrcBuffer array while pbEnd is greater than pbSrc.

But the problem here is that this condition is not checked consistently inside the loop. As you can see below, the advance variable is passed by reference to ExtractRunLength function. And then it is added to pbSrc:

View on GitHub!

/* libfreerdp/codec/interleaved.c */
...
runLength = ExtractRunLength(code, pbSrc, &advance);
pbSrc = pbSrc + advance;
SRCREADPIXEL(pixelA, pbSrc);
...

So, if pbSrc + advance is greater than pbEnd OOB read will occur resulting in accessing a memory location that is outside of the boundaries of the pbSrcBuffer array.

Impact

This issue may lead to Out-of-Bounds read.

CVE

Coordinated Disclosure Timeline

This report was subject to the GHSL coordinated disclosure policy.

Supporting Resources

Credit

This issue was discovered and reported by GHSL team member @antonio-morales (Antonio Morales).

Contact

You can contact the GHSL team at securitylab@github.com, please include the GHSL-2020-128 in any communication regarding this issue.