Combine poky (Yocto scarthgap), meta-openembedded (scarthgap), and meta-openwrt into a single repository. Components: - poky/ Yocto core framework (BitBake + OE-Core) - meta-openembedded/ Community layers (meta-oe, meta-python, meta-networking) - meta-openwrt/ OpenWrt customization layer - setup-env.sh One-click build environment setup - README.md Project documentation
76 lines
2.5 KiB
Diff
76 lines
2.5 KiB
Diff
From b590224c94effa3104a2db98a59478a9c4ed6f02 Mon Sep 17 00:00:00 2001
|
|
From: Armin Novak <armin.novak@thincast.com>
|
|
Date: Sat, 28 Feb 2026 11:38:23 +0100
|
|
Subject: [PATCH] [codec,h264] validate rectangles before use
|
|
|
|
CVE: CVE-2026-29774
|
|
Upstream-Status: Backport [https://github.com/FreeRDP/FreeRDP/commit/6482b7a92fff3959582cef052d1967ad6bde3738]
|
|
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
|
|
---
|
|
libfreerdp/codec/h264.c | 38 ++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 38 insertions(+)
|
|
|
|
diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c
|
|
index 718bd2ccf..13d592600 100644
|
|
--- a/libfreerdp/codec/h264.c
|
|
+++ b/libfreerdp/codec/h264.c
|
|
@@ -91,6 +91,36 @@ BOOL avc420_ensure_buffer(H264_CONTEXT* h264, UINT32 stride, UINT32 width, UINT3
|
|
return TRUE;
|
|
}
|
|
|
|
+static BOOL isRectValid(UINT32 width, UINT32 height, const RECTANGLE_16* rect)
|
|
+{
|
|
+ WINPR_ASSERT(rect);
|
|
+ if (rect->left > width)
|
|
+ return FALSE;
|
|
+ if (rect->right > width)
|
|
+ return FALSE;
|
|
+ if (rect->left >= rect->right)
|
|
+ return FALSE;
|
|
+ if (rect->top > height)
|
|
+ return FALSE;
|
|
+ if (rect->bottom > height)
|
|
+ return FALSE;
|
|
+ if (rect->top >= rect->bottom)
|
|
+ return FALSE;
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static BOOL areRectsValid(UINT32 width, UINT32 height, const RECTANGLE_16* rects, UINT32 count)
|
|
+{
|
|
+ WINPR_ASSERT(rects || (count == 0));
|
|
+ for (size_t x = 0; x < count; x++)
|
|
+ {
|
|
+ const RECTANGLE_16* rect = &rects[x];
|
|
+ if (!isRectValid(width, height, rect))
|
|
+ return FALSE;
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
INT32 avc420_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData,
|
|
DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight,
|
|
const RECTANGLE_16* regionRects, UINT32 numRegionRects)
|
|
@@ -101,6 +131,9 @@ INT32 avc420_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, UINT32 SrcSize
|
|
if (!h264 || h264->Compressor)
|
|
return -1001;
|
|
|
|
+ if (!areRectsValid(nDstWidth, nDstHeight, regionRects, numRegionRects))
|
|
+ return -1013;
|
|
+
|
|
status = h264->subsystem->Decompress(h264, pSrcData, SrcSize);
|
|
|
|
if (status == 0)
|
|
@@ -523,6 +556,11 @@ INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op, const RECTANGLE_16* regionR
|
|
if (!h264 || !regionRects || !pSrcData || !pDstData || h264->Compressor)
|
|
return -1001;
|
|
|
|
+ if (!areRectsValid(nDstWidth, nDstHeight, regionRects, numRegionRects))
|
|
+ return -1013;
|
|
+ if (!areRectsValid(nDstWidth, nDstHeight, auxRegionRects, numAuxRegionRect))
|
|
+ return -1014;
|
|
+
|
|
switch (op)
|
|
{
|
|
case 0: /* YUV420 in stream 1
|