]> git.kaiwu.me - haproxy.git/commit
IMPORT: slz/uslz: verify the trailer checksum before reporting completion
authorAurelien DARRAGON <adarragon@haproxy.com>
Tue, 11 Aug 2026 16:31:23 +0000 (18:31 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Wed, 12 Aug 2026 07:14:07 +0000 (09:14 +0200)
commit5f7d636b8b9621b65ce57f790400fea38b30167c
tree254c889778984507d4dec360c9498aed11514455
parenta641073ad684b79ecb885f110ee49e3f4f55b976
IMPORT: slz/uslz: verify the trailer checksum before reporting completion

uslz_decode_block() sets USLZ_FL_COMPLETE at the top of its completion
path, before reading and comparing the trailer checksum. If the trailer
bytes were not available yet, we jump to out_of_data, and uslz_decode()
then sees a complete stream in its drain path and jumps to end,
returning USLZ_DECODE_SUCCESS without ever calling uslz_decode_block()
again. Thus the checksum is never verified at all in this case, meaning
that under some scheduling circumstances, an invalid stream could appear
as valid.

On top of that, nothing ever assigns USLZ_ST_CHECK_CKSUM, so even if the
decoder had been called again, the state machine could not have resumed
in the middle of the trailer: it would have gone back to decoding symbols
and interpreted the trailer as deflate data.

The result was that a stream with a corrupted checksum was accepted,
silently, depending only on where the caller happened to cut its input.
On a 319-byte zlib stream the corruption went unnoticed at chunk sizes
1 to 7, 9, 15, 21, 35, 45 and 53, and on a 331-byte gzip stream with a
corrupted crc32 at 12, 13, 17, 18, 19, 25, 27, 36 and 54. (reminder,
deflate has no checksum).

This patch addresses this problem this way:

  - USLZ_ST_CHECK_CKSUM is set before reading the trailer, so that an
    out of data return really can resume there.

  - crc_flush is cleared after the final uslz_update_crc(), so as not
    to checksum the same bytes a second time in case of resume.

  - USLZ_FL_COMPLETE is set only *after* the comparison succeeded.

Now, trying to decode a corrupted trailer for either a zlib or gzip
stream properly reports a corruption (tested with 80 positions for each).

This is libslz upstream commit 1dc3cd773637477e5de33609d63527a0fd9bc4e7
src/uslz.c