]> dgit.raspbian.org Git - dovecot.git/commitdiff
[PATCH 3/4] lib-compression: istream-zstd - Guard against no-progress loop in read
authorAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 12 Jun 2026 11:19:42 +0000 (11:19 +0000)
committerNoah Meyerhans <noahm@debian.org>
Wed, 16 Sep 2026 19:06:35 +0000 (15:06 -0400)
If ZSTD_decompressStream() returns with neither input consumed nor
output produced, the read loop would spin indefinitely. Add a check
after each call: if input.pos is unchanged and output.pos is zero,
treat it as a corrupt stream (EIO).

Gbp-Pq: Name 0003-lib-compression-istream-zstd-Guard-against-no-progre.patch

src/lib-compression/istream-zstd.c

index 9e059bcffcee10997f6478a5730019bead8e0f31..b5505c8a09fac16e57bdcc11ce513b44b3e2c18b 100644 (file)
@@ -175,12 +175,20 @@ static ssize_t i_stream_zstd_read(struct istream_private *stream)
                zstream->output.pos = 0;
                zstream->output.size = ZSTD_DStreamOutSize();
 
+               size_t old_input_pos = zstream->input.pos;
                size_t zret = ZSTD_decompressStream(zstream->dstream, &zstream->output,
                                                    &zstream->input);
                if (ZSTD_isError(zret) != 0) {
                        i_stream_zstd_read_error(zstream, zret);
                        return -1;
                }
+               if (zstream->input.pos == old_input_pos && zstream->output.pos == 0) {
+                       io_stream_set_error(&zstream->istream.iostream,
+                                           "zstd.read(%s): decompressor made no progress",
+                                           i_stream_get_name(&zstream->istream.istream));
+                       zstream->istream.istream.stream_errno = EIO;
+                       return -1;
+               }
                /* ZSTD magic number is 4 bytes, but it's only defined after v0.8 */
                if (!zstream->hdr_read && zstream->input.size > 4)
                        zstream->hdr_read = TRUE;