]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
Remove the backdoor found in 5.6.0 and 5.6.1 (CVE-2024-3094).
authorLasse Collin <lasse.collin@tukaani.org>
Mon, 8 Apr 2024 12:32:58 +0000 (15:32 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Tue, 9 Apr 2024 14:57:39 +0000 (17:57 +0300)
While the backdoor was inactive (and thus harmless) without inserting
a small trigger code into the build system when the source package was
created, it's good to remove this anyway:

  - The executable payloads were embedded as binary blobs in
    the test files. This was a blatant violation of the
    Debian Free Software Guidelines.

  - On machines that see lots bots poking at the SSH port, the backdoor
    noticeably increased CPU load, resulting in degraded user experience
    and thus overwhelmingly negative user feedback.

  - The maintainer who added the backdoor has disappeared.

  - Backdoors are bad for security.

This reverts the following without making any other changes:

6e636819 Tests: Update two test files.
a3a29bbd Tests: Test --single-stream can decompress bad-3-corrupt_lzma2.xz.
0b4ccc91 Tests: Update RISC-V test files.
8c9b8b20 liblzma: Fix typos in crc32_fast.c and crc64_fast.c.
82ecc538 liblzma: Fix false Valgrind error report with GCC.
cf44e4b7 Tests: Add a few test files.
3060e107 Tests: Use smaller dictionary size in RISC-V test files.
e2870db5 Tests: Add two RISC-V Filter test files.

The RISC-V test files also have real content that tests the filter
but the real content would fit into much smaller files. A generator
program would need to be available as well.

Thanks to Andres Freund for finding and reporting it and making
it public quickly so others could act without a delay.
See: https://www.openwall.com/lists/oss-security/2024/03/29/4

12 files changed:
src/liblzma/check/crc32_fast.c
src/liblzma/check/crc64_fast.c
src/liblzma/check/crc_common.h
tests/files/README
tests/files/bad-3-corrupt_lzma2.xz [deleted file]
tests/files/bad-dict_size.lzma [deleted file]
tests/files/good-1-riscv-lzma2-1.xz [deleted file]
tests/files/good-1-riscv-lzma2-2.xz [deleted file]
tests/files/good-2cat.xz [deleted file]
tests/files/good-large_compressed.lzma [deleted file]
tests/files/good-small_compressed.lzma [deleted file]
tests/test_files.sh

index bfa295a0d1c877f367b2b1fdff880394c0667ed9..079051f12058978581388283c7507d3feef3c702 100644 (file)
@@ -135,8 +135,11 @@ typedef uint32_t (*crc32_func_type)(
 // This resolver is shared between all three dispatch methods. It serves as
 // the ifunc resolver if ifunc is supported, otherwise it is called as a
 // regular function by the constructor or first call resolution methods.
-// The function attributes are needed for safe IFUNC resolver usage with GCC.
-lzma_resolver_attributes
+// The __no_profile_instrument_function__ attribute support is checked when
+// determining if ifunc can be used, so it is safe to use here.
+#ifdef CRC_USE_IFUNC
+__attribute__((__no_profile_instrument_function__))
+#endif
 static crc32_func_type
 crc32_resolve(void)
 {
index 52cddb2c549e800f0ab6d68a0ef3e65fffe7ede2..5728b45ea06ea68d2430cc89acc940064440e1f9 100644 (file)
@@ -98,7 +98,9 @@ typedef uint64_t (*crc64_func_type)(
 #      pragma GCC diagnostic ignored "-Wunused-function"
 #endif
 
-lzma_resolver_attributes
+#ifdef CRC_USE_IFUNC
+__attribute__((__no_profile_instrument_function__))
+#endif
 static crc64_func_type
 crc64_resolve(void)
 {
index 5a86556f7a52cca54b679a98396badc0785ee9ce..856665db79a8d8793cbaf17b0ebab3aa3a0f06c8 100644 (file)
 #      endif
 #endif
 
-#ifdef CRC_USE_IFUNC
-// Two function attributes are needed to make IFUNC safe with GCC.
-//
-// no-omit-frame-pointer prevents false Valgrind issues when combined with
-// a few other compiler flags. The optimize attribute is supported on
-// GCC >= 4.4 and is not supported with Clang.
-#      if TUKLIB_GNUC_REQ(4,4) && !defined(__clang__)
-#              define no_omit_frame_pointer \
-                       __attribute__((optimize("no-omit-frame-pointer")))
-#      else
-#              define no_omit_frame_pointer
-#      endif
-
-// The __no_profile_instrument_function__ attribute support is checked when
-// determining if ifunc can be used, so it is safe to use unconditionally.
-// This attribute is needed because GCC can add profiling to the IFUNC
-// resolver, which calls functions that have not yet been relocated leading
-// to a crash on liblzma start up.
-#      define lzma_resolver_attributes \
-               __attribute__((__no_profile_instrument_function__)) \
-               no_omit_frame_pointer
-#else
-#      define lzma_resolver_attributes
-#endif
-
 // For CRC32 use the generic slice-by-eight implementation if no optimized
 // version is available.
 #if !defined(CRC32_ARCH_OPTIMIZED) && !defined(CRC32_GENERIC)
index e987a5193194907a75fe38bb36106dfd3e0f115f..a320845971ebbc07ecec4007c092674bc344971d 100644 (file)
@@ -41,8 +41,6 @@
     good-0catpad-empty.xz has two zero-Block Streams concatenated with
     four-byte Stream Padding between the Streams.
 
-    good-2cat.xz has two Streams with one Block each.
-
     good-1-check-none.xz has one Stream with one Block with two
     uncompressed LZMA2 chunks and no integrity check.
 
     good-1-arm64-lzma2-2.xz is like good-1-arm64-lzma2-1.xz but with
     non-zero start offset. XZ Embedded doesn't support this file.
 
-    good-1-riscv-lzma2-1.xz uses the RISC-V filter and LZMA2. The
-    uncompressed data is constructed so it tests all of the instructions
-    that should be encoded and a few that should not. Additionally, the
-    file contains random bytes to help test unforeseen corner cases.
-
-    good-1-riscv-lzma2-2.xz is like good-1-riscv-lzma2-1.xz but with
-    non-zero start offset. XZ Embedded doesn't support this file.
-
     good-1-lzma2-1.xz has two LZMA2 chunks, of which the second sets
     new properties.
 
     Uncompressed Size bytes of output will have been produced but
     the LZMA2 decoder doesn't indicate end of stream.
 
-    bad-3-corrupt_lzma2.xz has three Streams in it. The first and third
-    streams are valid xz Streams. The middle Stream has a correct Stream
-    Header, Block Header, Index and Stream Footer. Only the LZMA2 data
-    is corrupt. This file should decompress if --single-stream is used.
-
 
 3. Descriptions of Individual .lzma Files
 
     will give an error at the end of the file after producing the
     correct uncompressed output.
 
-    good-small_compressed.lzma was created with a small dictionary (2^16).
-    It contains the string "Hello World" repeated 100,000 times. This tests
-    match decoding and wrapping the dictionary.
-
-    good-large_compressed.lzma was created with a mix of repeated
-    characters and random data to test a data stream containing many
-    matches and many literals.
-
 
 3.2. Bad Files
 
     bad-too_small_size-without_eopm-3.lzma is like -1 above but instead
     of a literal the problem occurs in the middle of a match.
 
-    bad-dict_size.lzma has a valid dictionary size according to the .lzma
-    File Format, but will be rejected by XZ Utils because it is not 2^n or
-    2^n + 2^(n-1).
-
 
 4. Descriptions of Individual .lz (lzip) Files
 
diff --git a/tests/files/bad-3-corrupt_lzma2.xz b/tests/files/bad-3-corrupt_lzma2.xz
deleted file mode 100644 (file)
index f9ec69a..0000000
Binary files a/tests/files/bad-3-corrupt_lzma2.xz and /dev/null differ
diff --git a/tests/files/bad-dict_size.lzma b/tests/files/bad-dict_size.lzma
deleted file mode 100644 (file)
index f2ef5a5..0000000
Binary files a/tests/files/bad-dict_size.lzma and /dev/null differ
diff --git a/tests/files/good-1-riscv-lzma2-1.xz b/tests/files/good-1-riscv-lzma2-1.xz
deleted file mode 100644 (file)
index 85f3b75..0000000
Binary files a/tests/files/good-1-riscv-lzma2-1.xz and /dev/null differ
diff --git a/tests/files/good-1-riscv-lzma2-2.xz b/tests/files/good-1-riscv-lzma2-2.xz
deleted file mode 100644 (file)
index 60d2403..0000000
Binary files a/tests/files/good-1-riscv-lzma2-2.xz and /dev/null differ
diff --git a/tests/files/good-2cat.xz b/tests/files/good-2cat.xz
deleted file mode 100644 (file)
index ea4d627..0000000
Binary files a/tests/files/good-2cat.xz and /dev/null differ
diff --git a/tests/files/good-large_compressed.lzma b/tests/files/good-large_compressed.lzma
deleted file mode 100644 (file)
index 878991f..0000000
Binary files a/tests/files/good-large_compressed.lzma and /dev/null differ
diff --git a/tests/files/good-small_compressed.lzma b/tests/files/good-small_compressed.lzma
deleted file mode 100644 (file)
index a2fe802..0000000
Binary files a/tests/files/good-small_compressed.lzma and /dev/null differ
index 812b2152bd838b8033ef82185e6af786ed244920..16cb8619df884a3c23e47e9e4a400d81fc780754 100755 (executable)
@@ -149,17 +149,6 @@ else
        exit 1
 fi
 
-# Test that --single-stream can decompress bad-3-corrupt_lzma2.xz.
-# The first Stream in this file should decompress without errors.
-# This file cannot be decompressed with xzdec.
-I="$srcdir/files/bad-3-corrupt_lzma2.xz"
-if test -z "$XZ" || "$XZ" -dc --single-stream $NO_WARN "$I" > /dev/null; then
-       :
-else
-       echo "Good first Stream failed xz with --single-stream: $I"
-       exit 1
-fi
-
 
 #########
 # .lzma #