From 7b91be9b1ae71d04259b7bb73572e294014f53a2 Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Mon, 10 Aug 2026 15:34:47 +0800 Subject: [PATCH v3 3/3] Fix detection of truncated LZ4-compressed backups astreamer_lz4_decompressor did not check whether LZ4F_decompress() completed the final frame before finalizing. As a result, pg_verifybackup could accept a truncated LZ4-compressed tar backup. Record the decompression status and reject finalization unless the frame completed. Author: Chao Li Reviewed-by: Discussion: https://postgr.es/m/5962B878-C43D-4EBC-9E95-1F945CE5E586@gmail.com --- src/fe_utils/astreamer_lz4.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/fe_utils/astreamer_lz4.c b/src/fe_utils/astreamer_lz4.c index 12dfde2c837..d771d63972a 100644 --- a/src/fe_utils/astreamer_lz4.c +++ b/src/fe_utils/astreamer_lz4.c @@ -34,6 +34,7 @@ typedef struct astreamer_lz4_frame LZ4F_preferences_t prefs; size_t bytes_written; + size_t decompression_ret; bool header_written; } astreamer_lz4_frame; @@ -297,6 +298,9 @@ astreamer_lz4_decompressor_new(astreamer *next) pg_fatal("could not initialize compression library: %s", LZ4F_getErrorName(ctxError)); + /* Reject empty input, which does not contain a complete LZ4 frame. */ + streamer->decompression_ret = 1; + return &streamer->base; #else pg_fatal("this build does not support compression with %s", "LZ4"); @@ -358,6 +362,8 @@ astreamer_lz4_decompressor_content(astreamer *streamer, pg_fatal("could not decompress data: %s", LZ4F_getErrorName(ret)); + mystreamer->decompression_ret = ret; + /* Update input buffer based on number of bytes consumed */ avail_in -= read_size; next_in += read_size; @@ -395,6 +401,9 @@ astreamer_lz4_decompressor_finalize(astreamer *streamer) mystreamer = (astreamer_lz4_frame *) streamer; + if (mystreamer->decompression_ret != 0) + pg_fatal("could not decompress data: compressed stream is incomplete"); + /* * End of the stream, if there is some pending data in output buffers then * we must forward it to next streamer. -- 2.50.1 (Apple Git-155)