]> dgit.raspbian.org Git - dovecot.git/commitdiff
[PATCH] lib-compression: istream-lz4 - Ensure uncompressed chunk size is not 0
authorAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 23 Feb 2026 11:52:36 +0000 (13:52 +0200)
committerNoah Meyerhans <noahm@debian.org>
Wed, 16 Sep 2026 19:06:35 +0000 (15:06 -0400)
Gbp-Pq: Name 0001-lib-compression-istream-lz4-Ensure-uncompressed-chun.patch

src/lib-compression/istream-lz4.c
src/lib-compression/test-compression.c

index 24d539a96f2fe861eada9c7aebf8f5bcb86ec79a..b59604c5b44623115480db2b90e0ec34218b34f0 100644 (file)
@@ -77,9 +77,10 @@ static int i_stream_lz4_read_header(struct lz4_istream *zstream)
        zstream->max_uncompressed_chunk_size =
                be32_to_cpu_unaligned(hdr->max_uncompressed_chunk_size);
        buffer_set_used_size(zstream->chunk_buf, 0);
-       if (zstream->max_uncompressed_chunk_size > ISTREAM_LZ4_CHUNK_SIZE) {
+       if (zstream->max_uncompressed_chunk_size  == 0 ||
+           zstream->max_uncompressed_chunk_size > ISTREAM_LZ4_CHUNK_SIZE) {
                lz4_read_error(zstream, t_strdup_printf(
-                       "lz4 max chunk size too large (%u > %u)",
+                       "invalid lz4 max chunk size (%u, max %u)",
                        zstream->max_uncompressed_chunk_size,
                        ISTREAM_LZ4_CHUNK_SIZE));
                zstream->istream.istream.stream_errno = EINVAL;
index e035abff1a1a6d72f682aecd974e10cdf8e9e85d..1f9b6b9c10905a59492e9442a34cadc1165930e9 100644 (file)
@@ -1040,6 +1040,57 @@ static void test_lz4_small_header(void)
        test_end();
 }
 
+static const unsigned char lz4_chunk_crash_01[] = {
+        0x44, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x2d, 0x4c, 0x5a, 0x34, 0x0d,
+        0x2a, 0x9b, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x7a,
+        0x32, 0x01, 0xff, 0xff, 0x00, 0x30
+};
+
+static const unsigned char lz4_chunk_crash_02[] = {
+        0x44, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x2d, 0x4c, 0x5a, 0x34, 0x0d,
+        0x2a, 0x9b, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x7a,
+        0x32, 0x01, 0xff, 0xff, 0x00, 0x30
+};
+
+static void test_lz4_chunk_size(void)
+{
+       const struct compression_handler *lz4;
+       struct istream *file_input, *input;
+
+       if (compression_lookup_handler("lz4", &lz4) <= 0)
+               return; /* not compiled in or unknown */
+
+       test_begin("lz4 chunk size");
+
+       file_input = test_istream_create_data(lz4_chunk_crash_01,
+                                             sizeof(lz4_chunk_crash_01));
+       input = lz4->create_istream(file_input);
+       i_stream_unref(&file_input);
+       i_stream_read(input);
+
+       test_assert(input->eof);
+       test_assert(input->stream_errno != 0);
+       const char *error = i_stream_get_error(input);
+       test_assert(strstr(error, "invalid lz4 max chunk size") != NULL);
+
+       i_stream_unref(&input);
+
+       file_input = test_istream_create_data(lz4_chunk_crash_02,
+                                             sizeof(lz4_chunk_crash_02));
+       input = lz4->create_istream(file_input);
+       i_stream_unref(&file_input);
+       i_stream_read(input);
+
+       test_assert(input->eof);
+       test_assert(input->stream_errno != 0);
+       error = i_stream_get_error(input);
+       test_assert(strstr(error, "invalid lz4 max chunk size") != NULL);
+
+       i_stream_unref(&input);
+
+       test_end();
+}
+
 static void test_uncompress_file(const char *path)
 {
        const struct compression_handler *handler;
@@ -1163,6 +1214,7 @@ int main(int argc, char *argv[])
                test_gz_header,
                test_gz_large_header,
                test_lz4_small_header,
+               test_lz4_chunk_size,
                test_compression_ext,
                test_compression_deinit,
                NULL