From: Roman Neuhauser Date: Sun, 10 Apr 2011 09:13:35 +0000 (-0400) Subject: plug crashes in archive_read_support_filter_XXX X-Git-Tag: v3.0.0a~491 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab6c7f2aa50c4e4519f53d4685d46b28af2ab5ec;p=thirdparty%2Flibarchive.git plug crashes in archive_read_support_filter_XXX these functions lacked protection by archive_check_magic. SVN-Revision: 3195 --- diff --git a/Makefile.am b/Makefile.am index 6bfaa1230..b515c44f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -253,6 +253,7 @@ libarchive_test_SOURCES= \ libarchive/test/test_archive_read_set_format_option.c \ libarchive/test/test_archive_read_set_option.c \ libarchive/test/test_archive_read_set_options.c \ + libarchive/test/test_archive_read_support_filter_torture.c \ libarchive/test/test_archive_set_error.c \ libarchive/test/test_archive_string.c \ libarchive/test/test_archive_write_set_filter_option.c \ diff --git a/libarchive/archive_read_support_filter_all.c b/libarchive/archive_read_support_filter_all.c index 01eba82e7..263e88153 100644 --- a/libarchive/archive_read_support_filter_all.c +++ b/libarchive/archive_read_support_filter_all.c @@ -27,6 +27,7 @@ __FBSDID("$FreeBSD$"); #include "archive.h" +#include "archive_private.h" #if ARCHIVE_VERSION_NUMBER >= 4000000 #warning archive_read_support_compression_all @@ -41,6 +42,9 @@ archive_read_support_filter_all(struct archive *a) int archive_read_support_compression_all(struct archive *a) { + archive_check_magic(a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_all"); + /* Bzip falls back to "bunzip2" command-line */ archive_read_support_filter_bzip2(a); /* The decompress code doesn't use an outside library. */ diff --git a/libarchive/archive_read_support_filter_bzip2.c b/libarchive/archive_read_support_filter_bzip2.c index 894ddc907..35f66d8b4 100644 --- a/libarchive/archive_read_support_filter_bzip2.c +++ b/libarchive/archive_read_support_filter_bzip2.c @@ -88,6 +88,9 @@ archive_read_support_compression_bzip2(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *reader; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_bzip2"); + if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) return (ARCHIVE_FATAL); diff --git a/libarchive/archive_read_support_filter_compress.c b/libarchive/archive_read_support_filter_compress.c index 7ca02545b..aafd7f271 100644 --- a/libarchive/archive_read_support_filter_compress.c +++ b/libarchive/archive_read_support_filter_compress.c @@ -157,6 +157,9 @@ archive_read_support_compression_compress(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *bidder; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_compress"); + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) return (ARCHIVE_FATAL); diff --git a/libarchive/archive_read_support_filter_gzip.c b/libarchive/archive_read_support_filter_gzip.c index 51fdba8ce..c66280425 100644 --- a/libarchive/archive_read_support_filter_gzip.c +++ b/libarchive/archive_read_support_filter_gzip.c @@ -94,6 +94,9 @@ archive_read_support_compression_gzip(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *bidder; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_gzip"); + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) return (ARCHIVE_FATAL); diff --git a/libarchive/archive_read_support_filter_none.c b/libarchive/archive_read_support_filter_none.c index 9530ccb77..92ddf25c2 100644 --- a/libarchive/archive_read_support_filter_none.c +++ b/libarchive/archive_read_support_filter_none.c @@ -27,6 +27,7 @@ __FBSDID("$FreeBSD$"); #include "archive.h" +#include "archive_private.h" #if ARCHIVE_VERSION_NUMBER >= 4000000 #warning archive_read_support_compression_none @@ -45,6 +46,8 @@ archive_read_support_filter_none(struct archive *a) int archive_read_support_compression_none(struct archive *a) { - (void)a; /* UNUSED */ + archive_check_magic(a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_none"); + return (ARCHIVE_OK); } diff --git a/libarchive/archive_read_support_filter_rpm.c b/libarchive/archive_read_support_filter_rpm.c index 81f35c814..6d249ef1f 100644 --- a/libarchive/archive_read_support_filter_rpm.c +++ b/libarchive/archive_read_support_filter_rpm.c @@ -79,6 +79,9 @@ archive_read_support_compression_rpm(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *bidder; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_rpm"); + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) return (ARCHIVE_FATAL); diff --git a/libarchive/archive_read_support_filter_uu.c b/libarchive/archive_read_support_filter_uu.c index 95dd5e2e9..12f424080 100644 --- a/libarchive/archive_read_support_filter_uu.c +++ b/libarchive/archive_read_support_filter_uu.c @@ -79,6 +79,9 @@ archive_read_support_compression_uu(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *bidder; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_uu"); + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) return (ARCHIVE_FATAL); diff --git a/libarchive/archive_read_support_filter_xz.c b/libarchive/archive_read_support_filter_xz.c index 6f05d68a6..929b5968b 100644 --- a/libarchive/archive_read_support_filter_xz.c +++ b/libarchive/archive_read_support_filter_xz.c @@ -130,6 +130,9 @@ archive_read_support_compression_xz(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *bidder; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_xz"); + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) return (ARCHIVE_FATAL); @@ -163,6 +166,9 @@ archive_read_support_compression_lzma(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *bidder; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_lzma"); + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) return (ARCHIVE_FATAL); @@ -198,6 +204,9 @@ archive_read_support_compression_lzip(struct archive *_a) struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter_bidder *bidder; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_lzip"); + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) return (ARCHIVE_FATAL); diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt index 86fa40eb4..523b15f82 100644 --- a/libarchive/test/CMakeLists.txt +++ b/libarchive/test/CMakeLists.txt @@ -24,6 +24,7 @@ IF(ENABLE_TEST) test_archive_read_set_format_option.c test_archive_read_set_option.c test_archive_read_set_options.c + test_archive_read_support_filter_torture.c test_archive_set_error.c test_archive_string.c test_archive_write_set_filter_option.c diff --git a/libarchive/test/test_archive_read_support.h b/libarchive/test/test_archive_read_support.h new file mode 100644 index 000000000..ba8416856 --- /dev/null +++ b/libarchive/test/test_archive_read_support.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2011 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. + */ +__FBSDID("$FreeBSD$"); + +typedef struct archive *constructor(); +typedef int enabler(struct archive *); +typedef int destructor(struct archive *); + +static void +test_success(constructor new_, enabler enable_, destructor free_) +{ + struct archive *a = new_(); + assertEqualIntA(a, ARCHIVE_OK, enable_(a)); + assert(NULL == archive_error_string(a)); + assertEqualIntA(a, 0, archive_errno(a)); + free_(a); +} + +static void +test_failure(constructor new_, enabler enable_, destructor free_) +{ + struct archive *a = new_(); + assertEqualIntA(a, ARCHIVE_FATAL, enable_(a)); + assert(NULL != archive_error_string(a)); + assertEqualIntA(a, -1, archive_errno(a)); + free_(a); +} + +static void +test_filter_or_format(enabler enable) +{ + test_success(archive_read_new, enable, archive_read_free); + test_failure(archive_write_new, enable, archive_write_free); + test_failure(archive_read_disk_new, enable, archive_read_free); + test_failure(archive_write_disk_new, enable, archive_write_free); +} diff --git a/libarchive/test/test_archive_read_support_filter_torture.c b/libarchive/test/test_archive_read_support_filter_torture.c new file mode 100644 index 000000000..313182353 --- /dev/null +++ b/libarchive/test/test_archive_read_support_filter_torture.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2011 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" +__FBSDID("$FreeBSD$"); + +#include "test_archive_read_support.h" + +DEFINE_TEST(test_archive_read_support_filter_torture) +{ + test_filter_or_format(archive_read_support_filter_all); + test_filter_or_format(archive_read_support_filter_bzip2); + test_filter_or_format(archive_read_support_filter_compress); + test_filter_or_format(archive_read_support_filter_gzip); + test_filter_or_format(archive_read_support_filter_lzip); + test_filter_or_format(archive_read_support_filter_lzma); + test_filter_or_format(archive_read_support_filter_none); + test_filter_or_format(archive_read_support_filter_rpm); + test_filter_or_format(archive_read_support_filter_uu); + test_filter_or_format(archive_read_support_filter_xz); +}