From: Aki Tuomi Date: Fri, 12 Jun 2026 11:19:42 +0000 (+0000) Subject: [PATCH 3/4] lib-compression: istream-zstd - Guard against no-progress loop in read X-Git-Tag: archive/raspbian/1%2.4.1+dfsg1-6+rpi1+deb13u7^2~92 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=9ddba6188a1e2f5328b8caacb7328120a78b5e2b;p=dovecot.git [PATCH 3/4] lib-compression: istream-zstd - Guard against no-progress loop in read 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 --- diff --git a/src/lib-compression/istream-zstd.c b/src/lib-compression/istream-zstd.c index 9e059bc..b5505c8 100644 --- a/src/lib-compression/istream-zstd.c +++ b/src/lib-compression/istream-zstd.c @@ -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;