|
|
995285 |
From 9e0689cff30f64defb2691003143a7ad3126c74a Mon Sep 17 00:00:00 2001
|
|
|
995285 |
From: Tim Kientzle <kientzle@acm.org>
|
|
|
995285 |
Date: Sat, 7 Feb 2015 19:03:43 -0800
|
|
|
995285 |
Subject: [PATCH] Issue 406: Segfault on malformed Zip archive
|
|
|
995285 |
|
|
|
995285 |
Issue here was reading a size field as a signed number
|
|
|
995285 |
and then using that as an offset. Fixed by correctly
|
|
|
995285 |
masking the size value to an unsigned result.
|
|
|
995285 |
|
|
|
995285 |
Includes test based on the archive provided in the issue report.
|
|
|
995285 |
|
|
|
995285 |
---
|
|
|
995285 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
995285 |
index f6e1e20..fb90b9c 100644
|
|
|
995285 |
--- a/Makefile.am
|
|
|
995285 |
+++ b/Makefile.am
|
|
|
995285 |
@@ -428,6 +428,7 @@ libarchive_test_SOURCES= \
|
|
|
995285 |
libarchive/test/test_read_format_zip_comment_stored.c \
|
|
|
995285 |
libarchive/test/test_read_format_zip_filename.c \
|
|
|
995285 |
libarchive/test/test_read_format_zip_mac_metadata.c \
|
|
|
995285 |
+ libarchive/test/test_read_format_zip_malformed.c \
|
|
|
995285 |
libarchive/test/test_read_format_zip_sfx.c \
|
|
|
995285 |
libarchive/test/test_read_large.c \
|
|
|
995285 |
libarchive/test/test_read_pax_truncated.c \
|
|
|
995285 |
@@ -685,6 +686,7 @@ libarchive_test_EXTRA_DIST=\
|
|
|
995285 |
libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \
|
|
|
995285 |
libarchive/test/test_read_format_zip_length_at_end.zip.uu \
|
|
|
995285 |
libarchive/test/test_read_format_zip_mac_metadata.zip.uu \
|
|
|
995285 |
+ libarchive/test/test_read_format_zip_malformed1.zip.uu \
|
|
|
995285 |
libarchive/test/test_read_format_zip_sfx.uu \
|
|
|
995285 |
libarchive/test/test_read_format_zip_symlink.zip.uu \
|
|
|
995285 |
libarchive/test/test_read_format_zip_ux.zip.uu \
|
|
|
995285 |
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
|
|
|
995285 |
index 450a6f7..1aed84a 100644
|
|
|
995285 |
--- a/libarchive/archive_read_support_format_zip.c
|
|
|
995285 |
+++ b/libarchive/archive_read_support_format_zip.c
|
|
|
995285 |
@@ -1701,7 +1701,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
|
|
995285 |
if (datasize >= 1 && p[offset] == 1) {/* version=1 */
|
|
|
995285 |
if (datasize >= 4) {
|
|
|
995285 |
/* get a uid size. */
|
|
|
995285 |
- uidsize = p[offset+1];
|
|
|
995285 |
+ uidsize = 0xff & (int)p[offset+1];
|
|
|
995285 |
if (uidsize == 2)
|
|
|
995285 |
zip_entry->uid =
|
|
|
995285 |
archive_le16dec(
|
|
|
995285 |
@@ -1713,7 +1713,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
|
|
995285 |
}
|
|
|
995285 |
if (datasize >= (2 + uidsize + 3)) {
|
|
|
995285 |
/* get a gid size. */
|
|
|
995285 |
- gidsize = p[offset+2+uidsize];
|
|
|
995285 |
+ gidsize = 0xff & (int)p[offset+2+uidsize];
|
|
|
995285 |
if (gidsize == 2)
|
|
|
995285 |
zip_entry->gid =
|
|
|
995285 |
archive_le16dec(
|
|
|
995285 |
diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
|
|
|
995285 |
index 08770d9..2dc1740 100644
|
|
|
995285 |
--- a/libarchive/test/CMakeLists.txt
|
|
|
995285 |
+++ b/libarchive/test/CMakeLists.txt
|
|
|
995285 |
@@ -143,6 +143,7 @@ IF(ENABLE_TEST)
|
|
|
995285 |
test_read_format_zip_comment_stored.c
|
|
|
995285 |
test_read_format_zip_filename.c
|
|
|
995285 |
test_read_format_zip_mac_metadata.c
|
|
|
995285 |
+ test_read_format_zip_malformed.c
|
|
|
995285 |
test_read_format_zip_sfx.c
|
|
|
995285 |
test_read_large.c
|
|
|
995285 |
test_read_pax_truncated.c
|
|
|
995285 |
diff --git a/libarchive/test/test_read_format_zip_malformed.c b/libarchive/test/test_read_format_zip_malformed.c
|
|
|
995285 |
new file mode 100644
|
|
|
995285 |
index 0000000..2327d91
|
|
|
995285 |
--- /dev/null
|
|
|
995285 |
+++ b/libarchive/test/test_read_format_zip_malformed.c
|
|
|
995285 |
@@ -0,0 +1,61 @@
|
|
|
995285 |
+/*-
|
|
|
995285 |
+ * Copyright (c) 2003-2007 Tim Kientzle
|
|
|
995285 |
+ * Copyright (c) 2011 Michihiro NAKAJIMA
|
|
|
995285 |
+ * All rights reserved.
|
|
|
995285 |
+ *
|
|
|
995285 |
+ * Redistribution and use in source and binary forms, with or without
|
|
|
995285 |
+ * modification, are permitted provided that the following conditions
|
|
|
995285 |
+ * are met:
|
|
|
995285 |
+ * 1. Redistributions of source code must retain the above copyright
|
|
|
995285 |
+ * notice, this list of conditions and the following disclaimer.
|
|
|
995285 |
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
|
995285 |
+ * notice, this list of conditions and the following disclaimer in the
|
|
|
995285 |
+ * documentation and/or other materials provided with the distribution.
|
|
|
995285 |
+ *
|
|
|
995285 |
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
|
|
995285 |
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
995285 |
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
995285 |
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
995285 |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
995285 |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
995285 |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
995285 |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
995285 |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
995285 |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
995285 |
+ */
|
|
|
995285 |
+#include "test.h"
|
|
|
995285 |
+__FBSDID("$FreeBSD$");
|
|
|
995285 |
+
|
|
|
995285 |
+static void
|
|
|
995285 |
+test_malformed1(void)
|
|
|
995285 |
+{
|
|
|
995285 |
+ const char *refname = "test_read_format_zip_malformed1.zip";
|
|
|
995285 |
+ struct archive *a;
|
|
|
995285 |
+ struct archive_entry *ae;
|
|
|
995285 |
+ char *p;
|
|
|
995285 |
+ size_t s;
|
|
|
995285 |
+
|
|
|
995285 |
+ extract_reference_file(refname);
|
|
|
995285 |
+
|
|
|
995285 |
+ /* Verify with seeking reader. */
|
|
|
995285 |
+ assert((a = archive_read_new()) != NULL);
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
|
|
995285 |
+
|
|
|
995285 |
+ /* Verify with streaming reader. */
|
|
|
995285 |
+ p = slurpfile(&s, refname);
|
|
|
995285 |
+ assert((a = archive_read_new()) != NULL);
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
|
|
|
995285 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
|
|
995285 |
+}
|
|
|
995285 |
+
|
|
|
995285 |
+DEFINE_TEST(test_read_format_zip_malformed)
|
|
|
995285 |
+{
|
|
|
995285 |
+ test_malformed1();
|
|
|
995285 |
+}
|
|
|
995285 |
diff --git a/libarchive/test/test_read_format_zip_malformed1.zip.uu b/libarchive/test/test_read_format_zip_malformed1.zip.uu
|
|
|
995285 |
new file mode 100644
|
|
|
995285 |
index 0000000..cbd21a8
|
|
|
995285 |
--- /dev/null
|
|
|
995285 |
+++ b/libarchive/test/test_read_format_zip_malformed1.zip.uu
|
|
|
995285 |
@@ -0,0 +1,5 @@
|
|
|
995285 |
+begin 644 test_read_format_zip_malformed1.zip
|
|
|
995285 |
+M4$L#!#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`$`!P`,#`P,#`P"0`P,#`P,#`P
|
|
|
995285 |
+1,#!U>`L``80P,#`P,#`P,#``
|
|
|
995285 |
+`
|
|
|
995285 |
+end
|
|
|
995285 |
--
|
|
|
995285 |
2.7.4
|
|
|
995285 |
|