CVE-2016-7166 (C, published 2016-09-21T14:25Z)
Description: value: libarchive before 3.2.0 does not limit the number of recursive decompressions, which allows remote attackers to cause a denial of service (memory consumption and application crash) via a crafted gzip file.
Severity: MEDIUM (CVSS v3 base score: 5.5)
Weakness: CWE-399 \u2014 Resource Management Errors
Weaknesses in this category are related to improper management of system resources.
Repository: https://github.com/libarchive/libarchive
Files changed:
Makefile.am
libarchive/archive_read.c
libarchive/test/CMakeLists.txt
libarchive/test/test_read_too_many_filters.c
libarchive/test/test_read_too_many_filters.gz.uu
Commit message: Fix a potential crash issue discovered by Alexander Cherepanov:

It seems bsdtar automatically handles stacked compression. This is a
nice feature but it could be problematic when it's completely
unlimited.  Most clearly it's illustrated with quines:

$ curl -sRO http://www.maximumcompression.com/selfgz.gz
$ (ulimit -v 10000000 && bsdtar -tvf selfgz.gz)
bsdtar: Error opening archive: Can't allocate data for gzip decompression

Without ulimit, bsdtar will eat all available memory. This could also
be a problem for other applications using libarchive.


Vulnerable code:
	int number_bidders, i, bid, best_bid;
	for (;;) {

Fixed code:
	libarchive/test/test_read_too_many_filters.c \
	libarchive/test/test_read_too_many_filters.gz.uu \
	int number_bidders, i, bid, best_bid, n;
	for (n = 0; n < 25; ++n) {
	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
	    "Input requires too many filters for decoding");
	return (ARCHIVE_FATAL);
    test_read_too_many_filters.c
/*-
 * Copyright (c) 2003-2008,2015 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"

DEFINE_TEST(test_read_too_many_filters)
{
	const char *name = "test_read_too_many_filters.gz";
	struct archive *a;
	int r;

	assert((a = archive_read_new()) != NULL);
	r = archive_read_support_filter_gzip(a);
	if (r == ARCHIVE_WARN) {
		skipping("gzip reading not fully supported on this platform");
	}
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
	extract_reference_file(name);
	assertEqualIntA(a, ARCHIVE_FATAL,
	    archive_read_open_filename(a, name, 200));

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
This is a valid gzip file that decompresses to itself, from
  http://www.maximumcompression.com/selfgz.gz

This is used in test_read_too_many_filters to try to
crash libarchive by forcing it to spawn an unending
list of gunzip filters.

begin 644 test_read_too_many_filters.gz
M'XL(`````````P`/`/#_'XL(`````````P`/`/#_````__\```#__X)QH5P`
M`!X`X?\```#__P```/__@G&A7```'@#A_P```/__````__\```#__P```/__
M````__\```#__\(FAF`!`!0`Z_\```#__P```/__PB:&8`$`%`#K_\(FAF`!
M`!0`Z_^9(#6-B"@Q,C,T`K/`+```%`#K_P*SP"P``!0`Z_]"B"'$`````/__
>`P!#2DTAT@```$*((<0`````__\#`$-*32'2````
`
end