From e0bc548bf8bc5f204fdd5118694b8ceabfc02c8e Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Fri, 12 Mar 2021 10:15:51 +0100
Subject: [PATCH] Added missing bounds check.

---
 libfreerdp/codec/planar.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c
index f31c2d46acb9..8588a9e215e5 100644
--- a/libfreerdp/codec/planar.c
+++ b/libfreerdp/codec/planar.c
@@ -508,7 +508,7 @@ static INLINE BOOL writeLine(BYTE** ppRgba, UINT32 DstFormat, UINT32 width, cons
 static INLINE BOOL planar_decompress_planes_raw(const BYTE* pSrcData[4], BYTE* pDstData,
                                                 UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
                                                 UINT32 nYDst, UINT32 nWidth, UINT32 nHeight,
-                                                BOOL vFlip)
+                                                BOOL vFlip, UINT32 totalHeight)
 {
 	INT32 y;
 	INT32 beg, end, inc;
@@ -516,6 +516,7 @@ static INLINE BOOL planar_decompress_planes_raw(const BYTE* pSrcData[4], BYTE* p
 	const BYTE* pG = pSrcData[1];
 	const BYTE* pB = pSrcData[2];
 	const BYTE* pA = pSrcData[3];
+	const UINT32 bpp = GetBytesPerPixel(DstFormat);
 
 	if (vFlip)
 	{
@@ -530,9 +531,20 @@ static INLINE BOOL planar_decompress_planes_raw(const BYTE* pSrcData[4], BYTE* p
 		inc = 1;
 	}
 
+	if (nYDst + nHeight > totalHeight)
+		return FALSE;
+
+	if ((nXDst + nWidth) * bpp > nDstStep)
+		return FALSE;
+
 	for (y = beg; y != end; y += inc)
 	{
-		BYTE* pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * GetBytesPerPixel(DstFormat))];
+		BYTE* pRGB;
+
+		if (y > (INT64)nHeight)
+			return FALSE;
+
+		pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * bpp)];
 
 		if (!writeLine(&pRGB, DstFormat, nWidth, &pR, &pG, &pB, &pA))
 			return FALSE;
@@ -739,6 +751,7 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
 		UINT32 TempFormat;
 		BYTE* pTempData = pDstData;
 		UINT32 nTempStep = nDstStep;
+		UINT32 nTotalHeight = nYDst + nDstHeight;
 
 		if (useAlpha)
 			TempFormat = PIXEL_FORMAT_BGRA32;
@@ -749,12 +762,13 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
 		{
 			pTempData = planar->pTempData;
 			nTempStep = planar->nTempStep;
+			nTotalHeight = planar->maxHeight;
 		}
 
 		if (!rle) /* RAW */
 		{
 			if (!planar_decompress_planes_raw(planes, pTempData, TempFormat, nTempStep, nXDst,
-			                                  nYDst, nSrcWidth, nSrcHeight, vFlip))
+			                                  nYDst, nSrcWidth, nSrcHeight, vFlip, nTotalHeight))
 				return FALSE;
 
 			if (alpha)
@@ -819,6 +833,7 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
 		UINT32 TempFormat;
 		BYTE* pTempData = planar->pTempData;
 		UINT32 nTempStep = planar->nTempStep;
+		UINT32 nTotalHeight = planar->maxHeight;
 
 		if (useAlpha)
 			TempFormat = PIXEL_FORMAT_BGRA32;
@@ -901,7 +916,7 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
 			}
 
 			if (!planar_decompress_planes_raw(planes, pTempData, TempFormat, nTempStep, nXDst,
-			                                  nYDst, nSrcWidth, nSrcHeight, vFlip))
+			                                  nYDst, nSrcWidth, nSrcHeight, vFlip, nTotalHeight))
 				return FALSE;
 
 			if (alpha)

From a0be5cb87d760bb1c803ad1bb835aa1e73e62abc Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Mon, 16 Feb 2026 09:45:58 +0100
Subject: [PATCH] [codec,planar] fix missing destination bounds checks

---
 libfreerdp/codec/planar.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

Index: freerdp-2.11.7/libfreerdp/codec/planar.c
===================================================================
--- freerdp-2.11.7.orig/libfreerdp/codec/planar.c
+++ freerdp-2.11.7/libfreerdp/codec/planar.c
@@ -621,8 +621,10 @@ BOOL planar_decompress(BITMAP_PLANAR_CON
 	if (planar->maxHeight < nSrcHeight)
 		return FALSE;
 
+    const UINT32 bpp = GetBytesPerPixel(DstFormat);
+
 	if (nDstStep <= 0)
-		nDstStep = nDstWidth * GetBytesPerPixel(DstFormat);
+		nDstStep = nDstWidth * bpp;
 
 	srcp = pSrcData;
 
@@ -831,6 +833,24 @@ BOOL planar_decompress(BITMAP_PLANAR_CON
 		}
 		else /* RLE */
 		{
+			if (nYDst + nSrcHeight > nTotalHeight)
+			{
+				WLog_ERR(TAG,
+				         "planar plane destination Y %" PRIu32 " + height %" PRIu32
+				         " exceeds totalHeight %" PRIu32,
+				         nYDst, nSrcHeight, nTotalHeight);
+				return FALSE;
+			}
+
+			if ((nXDst + nSrcWidth) * bpp > nDstStep)
+			{
+				WLog_ERR(TAG,
+				         "planar plane destination (X %" PRIu32 " + width %" PRIu32
+				         ") * bpp %" PRIu32 " exceeds stride %" PRIu32,
+				         nXDst, nSrcWidth, bpp, nDstStep);
+				return FALSE;
+			}
+
 			status =
 			    planar_decompress_plane_rle(planes[0], rleSizes[0], pTempData, nTempStep, nXDst,
 			                                nYDst, nSrcWidth, nSrcHeight, 2, vFlip); /* RedPlane */
