From b7491675062cebd3bad2e56bfe8ba5c9790944bd Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Fri, 1 Dec 2023 20:42:54 +0200 Subject: [PATCH] LibCompress: Fix off-by-one error in generate_huffman_lengths Previously we would calculate the index of the first parent node as heap.size() (which is initialized to non_zero_freqs), so in the edge case in which all symbols had a non-zero frequency, we would use the Size-index entry in the array for both the first symbol's leaf node, and the first parent node. The result would either be a non-optimal huffman code (bad), or an illegal huffman code that would then go on to crash due to an error check in CanonicalCode::from_bytes. (worse) We now store parent nodes starting at heap.size() - 1, which eliminates the potential overlap, and resolves the issue. --- Tests/LibCompress/CMakeLists.txt | 1 + Tests/LibCompress/TestDeflate.cpp | 17 +++++++++++++++++ ...uzzDeflateCompression-6163230961303552.fuzz | Bin 0 -> 29687 bytes Userland/Libraries/LibCompress/Deflate.cpp | 6 +++--- 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 Tests/LibCompress/deflate-test-files/clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz diff --git a/Tests/LibCompress/CMakeLists.txt b/Tests/LibCompress/CMakeLists.txt index 691b5553a6..7d15595468 100644 --- a/Tests/LibCompress/CMakeLists.txt +++ b/Tests/LibCompress/CMakeLists.txt @@ -12,3 +12,4 @@ foreach(source IN LISTS TEST_SOURCES) endforeach() install(DIRECTORY brotli-test-files DESTINATION usr/Tests/LibCompress) +install(DIRECTORY deflate-test-files DESTINATION usr/Tests/LibCompress) diff --git a/Tests/LibCompress/TestDeflate.cpp b/Tests/LibCompress/TestDeflate.cpp index da53aefef2..2b5e8fc51f 100644 --- a/Tests/LibCompress/TestDeflate.cpp +++ b/Tests/LibCompress/TestDeflate.cpp @@ -11,8 +11,15 @@ #include #include #include +#include #include +#ifdef AK_OS_SERENITY +# define TEST_INPUT(x) ("/usr/Tests/LibCompress/deflate-test-files/" x) +#else +# define TEST_INPUT(x) ("deflate-test-files/" x) +#endif + TEST_CASE(canonical_code_simple) { Array const code { @@ -155,3 +162,13 @@ TEST_CASE(deflate_compress_literals) Array test { 0, 0, 0, 0, 0x72, 0, 0, 0xee, 0, 0, 0, 0x26, 0, 0, 0, 0x28, 0, 0, 0x72 }; auto compressed = TRY_OR_FAIL(Compress::DeflateCompressor::compress_all(test, Compress::DeflateCompressor::CompressionLevel::GOOD)); } + +TEST_CASE(ossfuzz_63183) +{ + auto path = TEST_INPUT("clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz"sv); + auto test_file = MUST(Core::File::open(path, Core::File::OpenMode::Read)); + auto test_data = MUST(test_file->read_until_eof()); + auto compressed = TRY_OR_FAIL(Compress::DeflateCompressor::compress_all(test_data, Compress::DeflateCompressor::CompressionLevel::GOOD)); + auto decompressed = TRY_OR_FAIL(Compress::DeflateDecompressor::decompress_all(compressed)); + EXPECT(test_data == decompressed); +} diff --git a/Tests/LibCompress/deflate-test-files/clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz b/Tests/LibCompress/deflate-test-files/clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz new file mode 100644 index 0000000000000000000000000000000000000000..91158016c0355599f2659c385c088d5999742686 GIT binary patch literal 29687 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 lengths, Array u16 heap_keys[Size]; // Used for O(n) heap construction u16 heap_values[Size]; - u16 huffman_links[Size * 2 + 1] = { 0 }; + u16 huffman_links[Size * 2] = { 0 }; size_t non_zero_freqs = 0; for (size_t i = 0; i < Size; i++) { auto frequency = frequencies[i]; @@ -657,7 +657,7 @@ void DeflateCompressor::generate_huffman_lengths(Array& lengths, Array u16 second_lowest_frequency = heap.peek_min_key(); u16 second_lowest_link = heap.pop_min(); - u16 new_link = heap.size() + 2; + u16 new_link = heap.size() + 1; heap.insert(lowest_frequency + second_lowest_frequency, new_link); @@ -676,7 +676,7 @@ void DeflateCompressor::generate_huffman_lengths(Array& lengths, Array non_zero_freqs++; size_t bit_length = 1; - while (link != 2) { + while (link != 1) { bit_length++; link = huffman_links[link]; }