From c2c5fffe1c01114f5b5573d03e40eec4991c6db3 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 7 Aug 2026 22:27:33 +0200 Subject: [PATCH 1/3] zstd: Remove redundant errno.h include Signed-off-by: Tobias Stoeckmann --- libarchive/archive_read_support_filter_zstd.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libarchive/archive_read_support_filter_zstd.c b/libarchive/archive_read_support_filter_zstd.c index 163f54b5..89406e38 100644 --- a/libarchive/archive_read_support_filter_zstd.c +++ b/libarchive/archive_read_support_filter_zstd.c @@ -25,10 +25,6 @@ #include "archive_platform.h" -#ifdef HAVE_ERRNO_H -#include -#endif - #ifdef HAVE_ERRNO_H #include #endif From 978a9184ec2464713d940b146cd64bc99e1ff568 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 7 Aug 2026 22:27:58 +0200 Subject: [PATCH 2/3] lz4/zstd: Always check upper bid byte limit If upstream filter provides huge amount of bytes, e.g. if archive is fully stored in memory, bidding accesses too many bytes. This could in turn overflow int return value, possibly leading to signed integer overflows. Signed-off-by: Tobias Stoeckmann --- libarchive/archive_read_support_filter_lz4.c | 6 ++---- libarchive/archive_read_support_filter_zstd.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/libarchive/archive_read_support_filter_lz4.c b/libarchive/archive_read_support_filter_lz4.c index 28189a07..a855f1fe 100644 --- a/libarchive/archive_read_support_filter_lz4.c +++ b/libarchive/archive_read_support_filter_lz4.c @@ -205,13 +205,11 @@ lz4_reader_bid(struct archive_read_filter_bidder *b, * if this is LZ4 data. */ if (archive_ckd_add_size(&min, - offset_in_buffer, min_lz4_frame_size)) + offset_in_buffer, min_lz4_frame_size) || + min > max_lookahead) return (0); /* TODO: should this be >= ? */ if (min > (size_t)avail) { - if (min > max_lookahead) - return (0); - buffer = __archive_read_filter_ahead(f, min, &avail); if (buffer == NULL) diff --git a/libarchive/archive_read_support_filter_zstd.c b/libarchive/archive_read_support_filter_zstd.c index 89406e38..b4df94ad 100644 --- a/libarchive/archive_read_support_filter_zstd.c +++ b/libarchive/archive_read_support_filter_zstd.c @@ -168,12 +168,10 @@ zstd_bidder_bid(struct archive_read_filter_bidder *b, * if this is zstd data. */ if (archive_ckd_add_size(&min, - offset_in_buffer, min_zstd_frame_size)) + offset_in_buffer, min_zstd_frame_size) || + min > max_lookahead) return (0); if (min > (size_t)avail) { - if (min > max_lookahead) - return (0); - buffer = __archive_read_filter_ahead(f, min, &avail); if (buffer == NULL) From f815fc44e6ed3511dc6f6067ff7752da478335f2 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 7 Aug 2026 22:40:33 +0200 Subject: [PATCH 3/3] lz4/zstd: Count bits in bidder, not bytes All other filters count bits as bidding result. Do so here as well. Signed-off-by: Tobias Stoeckmann --- libarchive/archive_read_support_filter_lz4.c | 2 +- libarchive/archive_read_support_filter_zstd.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libarchive/archive_read_support_filter_lz4.c b/libarchive/archive_read_support_filter_lz4.c index a855f1fe..83e00ccb 100644 --- a/libarchive/archive_read_support_filter_lz4.c +++ b/libarchive/archive_read_support_filter_lz4.c @@ -180,6 +180,7 @@ lz4_reader_bid(struct archive_read_filter_bidder *b, uint32_t frame_data_size; /* Skip over the magic number */ + bits_checked += 28; offset_in_buffer += 4; /* Ensure that we can read another 4 bytes. */ @@ -224,7 +225,6 @@ lz4_reader_bid(struct archive_read_filter_bidder *b, * follows, or this isn't LZ4 data. */ - bits_checked = offset_in_buffer; buffer = buffer + offset_in_buffer; if (magic_number == LZ4_MAGICNUMBER) { diff --git a/libarchive/archive_read_support_filter_zstd.c b/libarchive/archive_read_support_filter_zstd.c index b4df94ad..c676d62b 100644 --- a/libarchive/archive_read_support_filter_zstd.c +++ b/libarchive/archive_read_support_filter_zstd.c @@ -105,6 +105,7 @@ zstd_bidder_bid(struct archive_read_filter_bidder *b, { const unsigned char *buffer; ssize_t avail; + int bits_checked = 0; /* * Zstandard skippable frames contain a 4 byte magic number followed * by a 4 byte frame data size, then that number of bytes of data. @@ -143,6 +144,7 @@ zstd_bidder_bid(struct archive_read_filter_bidder *b, uint32_t frame_data_size; /* Skip over the magic number */ + bits_checked += 28; offset_in_buffer += 4; /* Ensure that we can read another 4 bytes. */ @@ -187,7 +189,7 @@ zstd_bidder_bid(struct archive_read_filter_bidder *b, */ if (magic_number == zstd_magic) - return (offset_in_buffer + 4); + return (bits_checked + 32); return (0); }