From 2b5941610042262e2f81da150ec8b129380e509f Mon Sep 17 00:00:00 2001 From: Jakub Martisko Date: Thu, 19 Jun 2025 15:12:59 +0200 Subject: [PATCH] Fix CVE-2019-17543 Resolves: RHEL-87362 --- cve-2019-17543-part1.patch | 22 +++++++++++ cve-2019-17543-part2.patch | 79 ++++++++++++++++++++++++++++++++++++++ cve-2019-17543-part3.patch | 22 +++++++++++ lz4.spec | 9 ++++- 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 cve-2019-17543-part1.patch create mode 100644 cve-2019-17543-part2.patch create mode 100644 cve-2019-17543-part3.patch diff --git a/cve-2019-17543-part1.patch b/cve-2019-17543-part1.patch new file mode 100644 index 0000000..b34bc39 --- /dev/null +++ b/cve-2019-17543-part1.patch @@ -0,0 +1,22 @@ +From 690009e2c2f9e5dcb0d40e7c0c40610ce6006eda Mon Sep 17 00:00:00 2001 +From: Nick Terrell +Date: Wed, 17 Jul 2019 11:07:24 -0700 +Subject: [PATCH] [LZ4_compress_destSize] Allow 2 more bytes of match length + +--- + lib/lz4.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/lz4.c b/lib/lz4.c +index 5b03e3d08..1e80c9812 100644 +--- a/lib/lz4.c ++++ b/lib/lz4.c +@@ -1016,7 +1016,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( + return 0; + if (outputLimited == fillOutput) { + /* Match description too long : reduce it */ +- U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 2 - 1 - LASTLITERALS) * 255; ++ U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 1 - LASTLITERALS) * 255; + ip -= matchCode - newMatchCode; + matchCode = newMatchCode; + } diff --git a/cve-2019-17543-part2.patch b/cve-2019-17543-part2.patch new file mode 100644 index 0000000..873ba10 --- /dev/null +++ b/cve-2019-17543-part2.patch @@ -0,0 +1,79 @@ +From 6bc6f836a18d1f8fd05c8fc2b42f1d800bc25de1 Mon Sep 17 00:00:00 2001 +From: Nick Terrell +Date: Wed, 17 Jul 2019 11:28:38 -0700 +Subject: [PATCH] [LZ4_compress_destSize] Fix rare data corruption bug + +--- + lib/lz4.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/lib/lz4.c b/lib/lz4.c +index 1e80c9812..461644da0 100644 +--- a/lib/lz4.c ++++ b/lib/lz4.c +@@ -648,6 +648,18 @@ LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tab + return LZ4_hash4(LZ4_read32(p), tableType); + } + ++static void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) ++{ ++ switch (tableType) ++ { ++ default: /* fallthrough */ ++ case clearedTable: { /* illegal! */ assert(0); return; } ++ case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = NULL; return; } ++ case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = 0; return; } ++ case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = 0; return; } ++ } ++} ++ + static void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType) + { + switch (tableType) +@@ -848,6 +860,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( + for ( ; ; ) { + const BYTE* match; + BYTE* token; ++ const BYTE* filledIp; + + /* Find a match */ + if (tableType == byPtr) { +@@ -934,6 +947,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( + } + + /* Catch up */ ++ filledIp = ip; + while (((ip>anchor) & (match > lowLimit)) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; } + + /* Encode Literals */ +@@ -1018,7 +1032,21 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( + /* Match description too long : reduce it */ + U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 1 - LASTLITERALS) * 255; + ip -= matchCode - newMatchCode; ++ assert(newMatchCode < matchCode); + matchCode = newMatchCode; ++ if (unlikely(ip < filledIp)) { ++ /* We have already filled up to filledIp so if ip ends up less than filledIp ++ * we have positions in the hash table beyond the current position. This is ++ * a problem if we reuse the hash table. So we have to remove these positions ++ * from the hash table. ++ */ ++ const BYTE* ptr; ++ DEBUGLOG(5, "Clearing %u positions", (U32)(filledIp - ip)); ++ for (ptr = ip; ptr <= filledIp; ++ptr) { ++ U32 const h = LZ4_hashPosition(ptr, tableType); ++ LZ4_clearHash(h, cctx->hashTable, tableType); ++ } ++ } + } + } + if (matchCode >= ML_MASK) { +@@ -1038,6 +1066,8 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( + } else + *token += (BYTE)(matchCode); + } ++ /* Ensure we have enough space for the last literals. */ ++ assert(!(outputDirective == fillOutput && op + 1 + LASTLITERALS > olimit)); + + anchor = ip; + diff --git a/cve-2019-17543-part3.patch b/cve-2019-17543-part3.patch new file mode 100644 index 0000000..19b08e6 --- /dev/null +++ b/cve-2019-17543-part3.patch @@ -0,0 +1,22 @@ +From 13a2d9e34ffc4170720ce417c73e396d0ac1471a Mon Sep 17 00:00:00 2001 +From: Nick Terrell +Date: Wed, 17 Jul 2019 11:50:47 -0700 +Subject: [PATCH] [LZ4_compress_destSize] Fix overflow condition + +--- + lib/lz4.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/lz4.c b/lib/lz4.c +index 461644da0..74a9247ec 100644 +--- a/lib/lz4.c ++++ b/lib/lz4.c +@@ -1027,7 +1027,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( + } + + if ((outputLimited) && /* Check output buffer overflow */ +- (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) ) { ++ (unlikely(op + (1 + LASTLITERALS) + (matchCode+240)/255 > olimit)) ) { + if (outputLimited == limitedOutput) + return 0; + if (outputLimited == fillOutput) { diff --git a/lz4.spec b/lz4.spec index 95ed8bd..7c2ae8d 100644 --- a/lz4.spec +++ b/lz4.spec @@ -1,6 +1,6 @@ Name: lz4 Version: 1.8.3 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Extremely fast compression algorithm License: GPLv2+ and BSD @@ -10,6 +10,9 @@ Source0: https://github.com/Cyan4973/lz4/archive/v%{version}/%{name}-%{ve Obsoletes: %{name} < 1.7.5-3 Patch1: lz4-cve-2021-3520.patch +Patch2: cve-2019-17543-part1.patch +Patch3: cve-2019-17543-part2.patch +Patch4: cve-2019-17543-part3.patch %description LZ4 is an extremely fast loss-less compression algorithm, providing compression @@ -81,6 +84,10 @@ chmod +x ./configure %{_libdir}/liblz4.a %changelog +* Thu Jun 19 2025 Jakub Martisko - 1.8.3-4 +- Fix CVE-2019-17543 +- Resolves: RHEL-87362 + * Fri May 07 2021 Jakub Martisko - 1.8.3-3 - Fix memory corruption due to an integer overflow _ Resolves: CVE-2021-3520