mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-06-14 05:49:57 +00:00
freerdp: patch CVE-2023-40589
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 <skandigraun@gmail.com>
This commit is contained in:
@@ -0,0 +1,319 @@
|
|||||||
|
From 2bbed980cf8cf9066d96e9aa29afcedc540ee47c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Armin Novak <armin.novak@thincast.com>
|
||||||
|
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 <skandigraun@gmail.com>
|
||||||
|
---
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -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-39353.patch \
|
||||||
file://CVE-2023-40181.patch \
|
file://CVE-2023-40181.patch \
|
||||||
file://CVE-2023-40569.patch \
|
file://CVE-2023-40569.patch \
|
||||||
|
file://CVE-2023-40589.patch \
|
||||||
"
|
"
|
||||||
|
|
||||||
S = "${WORKDIR}/git"
|
S = "${WORKDIR}/git"
|
||||||
|
|||||||
Reference in New Issue
Block a user