Details: https://nvd.nist.gov/vuln/detail/CVE-2023-40589

Pick the patch that was identified[1] by Debian to solve the issue
on the 2.x branch.

[1]: https://security-tracker.debian.org/tracker/CVE-2023-40589

Signed-off-by: Gyorgy Sarvari <[email protected]>
---
 .../freerdp/freerdp/CVE-2023-40589.patch      | 319 ++++++++++++++++++
 .../recipes-support/freerdp/freerdp_2.6.1.bb  |   1 +
 2 files changed, 320 insertions(+)
 create mode 100644 meta-oe/recipes-support/freerdp/freerdp/CVE-2023-40589.patch

diff --git a/meta-oe/recipes-support/freerdp/freerdp/CVE-2023-40589.patch 
b/meta-oe/recipes-support/freerdp/freerdp/CVE-2023-40589.patch
new file mode 100644
index 0000000000..8f87cae3b6
--- /dev/null
+++ b/meta-oe/recipes-support/freerdp/freerdp/CVE-2023-40589.patch
@@ -0,0 +1,319 @@
+From 2bbed980cf8cf9066d96e9aa29afcedc540ee47c Mon Sep 17 00:00:00 2001
+From: Armin Novak <[email protected]>
+Date: Mon, 28 Aug 2023 09:06:42 +0200
+Subject: [PATCH] fix index checks
+
+properly verify all offsets while decoding data.
+
+(cherry picked from commit 880285c332a1d98334fd8fa4b06c10fba0fb6959)
+
+CVE: CVE-2023-40589
+Upstream-Status: Backport 
[https://github.com/FreeRDP/FreeRDP/commit/c659973bb4cd65c065f2fe1a807dbc6805c684c6]
+Signed-off-by: Gyorgy Sarvari <[email protected]>
+---
+ libfreerdp/codec/ncrush.c | 137 ++++++++++++++++++++++++++++++--------
+ 1 file changed, 108 insertions(+), 29 deletions(-)
+
+diff --git a/libfreerdp/codec/ncrush.c b/libfreerdp/codec/ncrush.c
+index 3d6a216d3..c1d622a9c 100644
+--- a/libfreerdp/codec/ncrush.c
++++ b/libfreerdp/codec/ncrush.c
+@@ -1994,15 +1994,9 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+                       UINT32* pDstSize, UINT32 flags)
+ {
+       UINT32 index;
+-      UINT32 bits;
+-      INT32 nbits;
+-      const BYTE* SrcPtr;
+-      const BYTE* SrcEnd;
+-      UINT16 Mask;
+       BYTE Literal;
+       UINT32 IndexLEC;
+       UINT32 BitLength;
+-      UINT32 MaskedBits;
+       UINT32 CopyOffset;
+       UINT32 CopyLength;
+       UINT32 OldCopyOffset;
+@@ -2010,9 +2004,6 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+       UINT32 LengthOfMatch;
+       UINT32 CopyOffsetIndex;
+       UINT32 OffsetCacheIndex;
+-      BYTE* HistoryPtr;
+-      BYTE* HistoryBuffer;
+-      BYTE* HistoryBufferEnd;
+       UINT32 CopyOffsetBits;
+       UINT32 CopyOffsetBase;
+       UINT32 LengthOfMatchBits;
+@@ -2021,8 +2012,8 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+       if (ncrush->HistoryEndOffset != 65535)
+               return -1001;
+ 
+-      HistoryBuffer = ncrush->HistoryBuffer;
+-      HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
++      BYTE* HistoryBuffer = ncrush->HistoryBuffer;
++      const BYTE* HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
+ 
+       if (flags & PACKET_AT_FRONT)
+       {
+@@ -2041,7 +2032,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+               ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
+       }
+ 
+-      HistoryPtr = ncrush->HistoryPtr;
++      BYTE* HistoryPtr = ncrush->HistoryPtr;
+ 
+       if (!(flags & PACKET_COMPRESSED))
+       {
+@@ -2050,17 +2041,19 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+               return 1;
+       }
+ 
+-      SrcEnd = &pSrcData[SrcSize];
+-      nbits = 32;
+-      bits = get_dword(pSrcData);
+-      SrcPtr = pSrcData + 4;
++      const BYTE* SrcEnd = &pSrcData[SrcSize];
++      const BYTE* SrcPtr = pSrcData + 4;
+ 
++      INT32 nbits = 32;
++      UINT32 bits = get_dword(pSrcData);
+       while (1)
+       {
+               while (1)
+               {
+-                      Mask = get_word(&HuffTableMask[29]);
+-                      MaskedBits = bits & Mask;
++                      const UINT16 Mask = get_word(&HuffTableMask[29]);
++                      const UINT32 MaskedBits = bits & Mask;
++                      if (MaskedBits >= ARRAYSIZE(HuffTableLEC))
++                              return -1;
+                       IndexLEC = HuffTableLEC[MaskedBits] & 0xFFF;
+                       BitLength = HuffTableLEC[MaskedBits] >> 12;
+                       bits >>= BitLength;
+@@ -2096,8 +2089,10 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+                               return -1004;
+ 
+                       CopyOffset = ncrush->OffsetCache[OffsetCacheIndex];
+-                      Mask = get_word(&HuffTableMask[21]);
+-                      MaskedBits = bits & Mask;
++                      const UINT16 Mask = get_word(&HuffTableMask[21]);
++                      const UINT32 MaskedBits = bits & Mask;
++                      if (MaskedBits > ARRAYSIZE(HuffTableLOM))
++                              return -1;
+                       LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
+                       BitLength = HuffTableLOM[MaskedBits] >> 12;
+                       bits >>= BitLength;
+@@ -2106,13 +2101,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+                       if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
+                               return -1;
+ 
++                      if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
++                              return -1;
++
+                       LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
++
++                      if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
++                              return -1;
+                       LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
+ 
+                       if (LengthOfMatchBits)
+                       {
+-                              Mask = get_word(&HuffTableMask[(2 * 
LengthOfMatchBits) + 3]);
+-                              MaskedBits = bits & Mask;
++                              const size_t idx = (2ull * LengthOfMatchBits) + 
3ull;
++                              if (idx >= ARRAYSIZE(HuffTableMask))
++                                      return -1;
++
++                              const UINT16 Mask = 
get_word(&HuffTableMask[idx]);
++                              const UINT32 MaskedBits = bits & Mask;
+                               bits >>= LengthOfMatchBits;
+                               nbits -= LengthOfMatchBits;
+                               LengthOfMatchBase += MaskedBits;
+@@ -2127,15 +2132,28 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+               }
+               else
+               {
++                      if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBitsLUT))
++                              return -1;
++
+                       CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
++
++                      if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBaseLUT))
++                              return -1;
+                       CopyOffsetBase = CopyOffsetBaseLUT[CopyOffsetIndex];
+                       CopyOffset = CopyOffsetBase - 1;
+ 
+                       if (CopyOffsetBits)
+                       {
+-                              Mask = get_word(&HuffTableMask[(2 * 
CopyOffsetBits) + 3]);
+-                              MaskedBits = bits & Mask;
+-                              CopyOffset = CopyOffsetBase + MaskedBits - 1;
++                              const size_t idx = (2ull * CopyOffsetBits) + 
3ull;
++                              if (idx >= ARRAYSIZE(HuffTableMask))
++                                      return -1;
++
++                              const UINT16 Mask = 
get_word(&HuffTableMask[idx]);
++                              const UINT32 MaskedBits = bits & Mask;
++                              const UINT32 tmp = CopyOffsetBase + MaskedBits;
++                              if (tmp < 1)
++                                      return -1;
++                              CopyOffset = tmp - 1;
+                               bits >>= CopyOffsetBits;
+                               nbits -= CopyOffsetBits;
+ 
+@@ -2143,8 +2161,11 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+                                       return -1;
+                       }
+ 
+-                      Mask = get_word(&HuffTableMask[21]);
+-                      MaskedBits = bits & Mask;
++                      const UINT16 Mask = get_word(&HuffTableMask[21]);
++                      const UINT32 MaskedBits = bits & Mask;
++                      if (MaskedBits >= ARRAYSIZE(HuffTableLOM))
++                              return -1;
++
+                       LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
+                       BitLength = HuffTableLOM[MaskedBits] >> 12;
+                       bits >>= BitLength;
+@@ -2153,13 +2174,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BY
+                       if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
+                               return -1;
+ 
++                      if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
++                              return -1;
++
+                       LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
++
++                      if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
++                              return -1;
+                       LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
+ 
+                       if (LengthOfMatchBits)
+                       {
+-                              Mask = get_word(&HuffTableMask[(2 * 
LengthOfMatchBits) + 3]);
+-                              MaskedBits = bits & Mask;
++                              const size_t idx = (2ull * LengthOfMatchBits) + 
3ull;
++                              if (idx >= ARRAYSIZE(HuffTableMask))
++                                      return -1;
++
++                              const UINT16 Mask = 
get_word(&HuffTableMask[idx]);
++                              const UINT32 MaskedBits = bits & Mask;
+                               bits >>= LengthOfMatchBits;
+                               nbits -= LengthOfMatchBits;
+                               LengthOfMatchBase += MaskedBits;
+@@ -2583,7 +2614,12 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BYTE
+                       }
+ 
+                       IndexLEC = Literal;
++                      if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
++                              return -1;
+                       BitLength = HuffLengthLEC[IndexLEC];
++
++                      if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
++                              return -1;
+                       CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
+ 
+                       if (BitLength > 15)
+@@ -2666,9 +2702,18 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BYTE
+                                       bits = CopyOffset;
+ 
+                               CopyOffsetIndex = 
ncrush->HuffTableCopyOffset[bits + 2];
++
++                              if (CopyOffsetIndex >= 
ARRAYSIZE(CopyOffsetBitsLUT))
++                                      return -1;
++
+                               CopyOffsetBits = 
CopyOffsetBitsLUT[CopyOffsetIndex];
+                               IndexLEC = 257 + CopyOffsetIndex;
++                              if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
++                                      return -1;
+                               BitLength = HuffLengthLEC[IndexLEC];
++
++                              if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
++                                      return -1;
+                               CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
+ 
+                               if (BitLength > 15)
+@@ -2687,13 +2732,23 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BYTE
+                               else
+                                       IndexCO = 
ncrush->HuffTableLOM[MatchLength];
+ 
++                              if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
++                                      return -1;
+                               BitLength = HuffLengthLOM[IndexCO];
++
++                              if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
++                                      return -1;
+                               IndexLOM = LOMBitsLUT[IndexCO];
++
++                              if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
++                                      return -1;
+                               NCrushWriteBits(&DstPtr, &accumulator, &offset, 
HuffCodeLOM[IndexCO], BitLength);
+                               Mask = ((1 << IndexLOM) - 1);
+                               MaskedBits = (MatchLength - 2) & Mask;
+                               NCrushWriteBits(&DstPtr, &accumulator, &offset, 
MaskedBits, IndexLOM);
+ 
++                              if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
++                                      return -1;
+                               if ((MaskedBits + LOMBaseLUT[IndexCO]) != 
MatchLength)
+                                       return -1010;
+                       }
+@@ -2701,7 +2756,11 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BYTE
+                       {
+                               /* CopyOffset in OffsetCache */
+                               IndexLEC = 289 + OffsetCacheIndex;
++                              if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
++                                      return -1;
+                               BitLength = HuffLengthLEC[IndexLEC];
++                              if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
++                                      return -1;
+                               CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
+ 
+                               if (BitLength >= 15)
+@@ -2714,13 +2773,24 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BYTE
+                               else
+                                       IndexCO = 
ncrush->HuffTableLOM[MatchLength];
+ 
++                              if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
++                                      return -1;
++
+                               BitLength = HuffLengthLOM[IndexCO];
++
++                              if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
++                                      return -1;
+                               IndexLOM = LOMBitsLUT[IndexCO];
++
++                              if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
++                                      return -1;
+                               NCrushWriteBits(&DstPtr, &accumulator, &offset, 
HuffCodeLOM[IndexCO], BitLength);
+                               Mask = ((1 << IndexLOM) - 1);
+                               MaskedBits = (MatchLength - 2) & Mask;
+                               NCrushWriteBits(&DstPtr, &accumulator, &offset, 
MaskedBits, IndexLOM);
+ 
++                              if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
++                                      return -1;
+                               if ((MaskedBits + LOMBaseLUT[IndexCO]) != 
MatchLength)
+                                       return -1012;
+                       }
+@@ -2745,6 +2815,10 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* 
pSrcData, UINT32 SrcSize, BYTE
+               Literal = *SrcPtr++;
+               HistoryPtr++;
+               IndexLEC = Literal;
++              if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
++                      return -1;
++              if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
++                      return -1;
+               BitLength = HuffLengthLEC[IndexLEC];
+               CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
+ 
+@@ -2817,6 +2891,11 @@ static int ncrush_generate_tables(NCRUSH_CONTEXT* 
context)
+               else
+                       i = context->HuffTableLOM[k];
+ 
++              if (i >= ARRAYSIZE(LOMBitsLUT))
++                      return -1;
++              if (i >= ARRAYSIZE(LOMBaseLUT))
++                      return -1;
++
+               if (((((1 << LOMBitsLUT[i]) - 1) & (k - 2)) + LOMBaseLUT[i]) != 
k)
+                       return -1;
+       }
diff --git a/meta-oe/recipes-support/freerdp/freerdp_2.6.1.bb 
b/meta-oe/recipes-support/freerdp/freerdp_2.6.1.bb
index 5122a2d057..e422d46a81 100644
--- a/meta-oe/recipes-support/freerdp/freerdp_2.6.1.bb
+++ b/meta-oe/recipes-support/freerdp/freerdp_2.6.1.bb
@@ -30,6 +30,7 @@ SRC_URI = 
"git://github.com/FreeRDP/FreeRDP.git;branch=stable-2.0;protocol=https
            file://CVE-2023-39353.patch \
            file://CVE-2023-40181.patch \
            file://CVE-2023-40569.patch \
+           file://CVE-2023-40589.patch \
            "
 
 S = "${WORKDIR}/git"
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#123726): 
https://lists.openembedded.org/g/openembedded-devel/message/123726
Mute This Topic: https://lists.openembedded.org/mt/117395640/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to