Hi all,
(Andrew in CC, in case.)
While doing a post-commit review of 67d318e70402, I have noticed the
following coverage hole in pglz_decompress(), where a failure of this
check is not covered, see also [1]:
if (unlikely(off == 0 ||
off > (dp - (unsigned char *) dest)))
return -1;
This can be triggered easily with the two following sequences in the
regression tests:
SELECT test_pglz_decompress('\x011001'::bytea, 1024, true);
SELECT test_pglz_decompress('\x010300'::bytea, 1024, true);
It's unfortunately too late for this round of minor releases, but I'd
like to fix this hole once the next minor versions are tagged, down to
v14. If there are any objections or comments, feel free. Mea culpa.
Thanks,
[1]: https://coverage.postgresql.org/src/common/pg_lzcompress.c.gcov.html
--
Michael
From 4a63b443e241e98df27489ac04291822f4a56bc5 Mon Sep 17 00:00:00 2001 From: Michael Paquier <[email protected]> Date: Mon, 11 May 2026 15:21:30 +0900 Subject: [PATCH] Add more tests for corrupted data in pglz_decompress() Two cases fixed by 2b5ba2a0a141 were not covered, emulating corrupted data: - Set control bit with a valid 2-byte match tag where offset is 0. - Set control bit with a valid 2-byte match tag where offset exceeds output written. Oversight in 67d318e70402. Backpatch-through: 14 --- src/test/regress/expected/compression_pglz.out | 12 ++++++++++++ src/test/regress/sql/compression_pglz.sql | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/test/regress/expected/compression_pglz.out b/src/test/regress/expected/compression_pglz.out index 0ef49d425068..066a3317c65d 100644 --- a/src/test/regress/expected/compression_pglz.out +++ b/src/test/regress/expected/compression_pglz.out @@ -60,6 +60,18 @@ SELECT test_pglz_decompress('\x010f01'::bytea, 1024, false); ERROR: pglz_decompress failed SELECT test_pglz_decompress('\x010f01'::bytea, 1024, true); ERROR: pglz_decompress failed +-- Corrupted compressed data. Set control bit with a valid 2-byte match +-- tag where offset exceeds output written. +SELECT test_pglz_decompress('\x011001'::bytea, 1024, false); +ERROR: pglz_decompress failed +SELECT test_pglz_decompress('\x011001'::bytea, 1024, true); +ERROR: pglz_decompress failed +-- Corrupted compressed data. Set control bit with a valid 2-byte match +-- tag where offset is 0. +SELECT test_pglz_decompress('\x010300'::bytea, 1024, false); +ERROR: pglz_decompress failed +SELECT test_pglz_decompress('\x010300'::bytea, 1024, true); +ERROR: pglz_decompress failed -- Clean up DROP FUNCTION test_pglz_compress; DROP FUNCTION test_pglz_decompress; diff --git a/src/test/regress/sql/compression_pglz.sql b/src/test/regress/sql/compression_pglz.sql index a44af02afb7b..dbd37f7d4eb2 100644 --- a/src/test/regress/sql/compression_pglz.sql +++ b/src/test/regress/sql/compression_pglz.sql @@ -48,6 +48,16 @@ SELECT test_pglz_decompress('\x01ff'::bytea, 1024, true); SELECT test_pglz_decompress('\x010f01'::bytea, 1024, false); SELECT test_pglz_decompress('\x010f01'::bytea, 1024, true); +-- Corrupted compressed data. Set control bit with a valid 2-byte match +-- tag where offset exceeds output written. +SELECT test_pglz_decompress('\x011001'::bytea, 1024, false); +SELECT test_pglz_decompress('\x011001'::bytea, 1024, true); + +-- Corrupted compressed data. Set control bit with a valid 2-byte match +-- tag where offset is 0. +SELECT test_pglz_decompress('\x010300'::bytea, 1024, false); +SELECT test_pglz_decompress('\x010300'::bytea, 1024, true); + -- Clean up DROP FUNCTION test_pglz_compress; DROP FUNCTION test_pglz_decompress; -- 2.54.0
signature.asc
Description: PGP signature
