Skip to content

OutOfBound Read in planar_skip_plane_rle

Low
akallabeth published GHSA-vvr6-h646-mp4p Apr 22, 2024

Package

FreeRDP (C)

Affected versions

<= 3.4.0, <= 2.11.5

Patched versions

3.5.0, 2.11.6

Description

Impact

  • FreeRDP based Clients
BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT32 SrcSize,
                       UINT32 nSrcWidth, UINT32 nSrcHeight, BYTE* pDstData, UINT32 DstFormat,
                       UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst, UINT32 nDstWidth,
                       UINT32 nDstHeight, BOOL vFlip)
{
  ...
else /* RLE */
        {
                if (alpha)
                {
                        planes[3] = srcp;
[1]                        rleSizes[3] = planar_skip_plane_rle(planes[3], SrcSize - (planes[3] - pSrcData),
                                                            rawWidths[3], rawHeights[3]); /* AlphaPlane */
 
                        if (rleSizes[3] < 0)
                                return FALSE;

                        planes[0] = planes[3] + rleSizes[3];
                }
                else
                        planes[0] = srcp;

                rleSizes[0] = planar_skip_plane_rle(planes[0], SrcSize - (planes[0] - pSrcData),
                                                    rawWidths[0], rawHeights[0]); /* RedPlane */
}

static INLINE INT32 planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, UINT32 nWidth,
                                          UINT32 nHeight)
{
        UINT32 used = 0;
        BYTE controlByte = 0;
 
        WINPR_ASSERT(pSrcData);
 
        for (UINT32 y = 0; y < nHeight; y++)
        {
                for (UINT32 x = 0; x < nWidth;)
                {
                        int cRawBytes = 0;
                        int nRunLength = 0;

[2]                        if (used >= SrcSize)
                        {
                                WLog_ERR(TAG, "planar plane used %" PRIu32 " exceeds SrcSize %" PRIu32, used,
                                         SrcSize);
                                return -1;
                        }

[3]                        controlByte = pSrcData[used++];
                        nRunLength = PLANAR_CONTROL_BYTE_RUN_LENGTH(controlByte);
                        cRawBytes = PLANAR_CONTROL_BYTE_RAW_BYTES(controlByte);

1 - no checks for 'planes' array elements
2 - as a result SrcSize can exceed amount of available data
3 - out of bounds read on this line

Patches

Workarounds

  • Use /gfx or /rfx modes (on by default, require server side support)

References

  • Reported by Evgeny Legerov of Kaspersky Lab.
  • #10077

Severity

Low

CVE ID

CVE-2024-32458

Weaknesses

No CWEs