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);
Impact
FreeRDP
basedClients
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
/gfx
or/rfx
modes (on by default, require server side support)References