From: Tim Kientzle Date: Fri, 12 Sep 2025 16:01:13 +0000 (-0700) Subject: Ignore overlong gzip original_filename X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a2933fbefd179efd4de0033ee8f8bff6bca3eb77;p=thirdparty%2Flibarchive.git Ignore overlong gzip original_filename We reuse the compression buffer to format the gzip header, but didn't check for an overlong gzip original_filename. This adds that check. If the original_filename is over 32k (or bigger than the buffer in case someone shrinks the buffer someday), we WARN and ignore the filename. --- diff --git a/libarchive/archive_write_add_filter_gzip.c b/libarchive/archive_write_add_filter_gzip.c index 5ef43c193..49fbc6380 100644 --- a/libarchive/archive_write_add_filter_gzip.c +++ b/libarchive/archive_write_add_filter_gzip.c @@ -191,7 +191,8 @@ static int archive_compressor_gzip_open(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int ret; + int ret = ARCHIVE_OK; + int init_success; if (data->compressed == NULL) { size_t bs = 65536, bpb; @@ -241,24 +242,43 @@ archive_compressor_gzip_open(struct archive_write_filter *f) data->stream.avail_out -= 10; if (data->original_filename != NULL) { - strcpy((char*)data->compressed + 10, data->original_filename); - data->stream.next_out += strlen(data->original_filename) + 1; - data->stream.avail_out -= strlen(data->original_filename) + 1; + /* Limit "original filename" to 32k or the + * remaining space in the buffer, whichever is smaller. + */ + int ofn_length = strlen(data->original_filename); + int ofn_max_length = 32768; + int ofn_space_available = data->compressed + + data->compressed_buffer_size + - data->stream.next_out + - 1; + if (ofn_max_length > ofn_space_available) { + ofn_max_length = ofn_space_available; + } + if (ofn_length < ofn_max_length) { + strcpy((char*)data->compressed + 10, + data->original_filename); + data->stream.next_out += ofn_length + 1; + data->stream.avail_out -= ofn_length + 1; + } else { + archive_set_error(&a->archive, ENOMEM, + "Gzip 'Original Filename' ignored because it is too long"); + ret = ARCHIVE_WARN; + } } f->write = archive_compressor_gzip_write; /* Initialize compression library. */ - ret = deflateInit2(&(data->stream), + init_success = deflateInit2(&(data->stream), data->compression_level, Z_DEFLATED, -15 /* < 0 to suppress zlib header */, 8, Z_DEFAULT_STRATEGY); - if (ret == Z_OK) { + if (init_success == Z_OK) { f->data = data; - return (ARCHIVE_OK); + return (ret); } /* Library setup failed: clean up. */ @@ -266,7 +286,7 @@ archive_compressor_gzip_open(struct archive_write_filter *f) "initializing compression library"); /* Override the error message if we know what really went wrong. */ - switch (ret) { + switch (init_success) { case Z_STREAM_ERROR: archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Internal error initializing "