e7c1099
From df29aeb7db98d227aea966b18261e5c1d97d223a Mon Sep 17 00:00:00 2001
e7c1099
From: Pavel Raiskup <praiskup@redhat.com>
e7c1099
Date: Wed, 29 Apr 2015 10:23:01 +0200
e7c1099
Subject: [PATCH] Upstream 3865cf2bc e6c9668f 24f5de65 --- From: Tim Kientzle
e7c1099
 <kientzle@acm.org> Date: Fri, 30 Jan 2015 23:54:19 -0800 Subject: [PATCH]
e7c1099
 Issue 394: Segfault when reading malformed     old-style cpio archives
e7c1099
e7c1099
Root cause here was an implicit cast that resulted in
e7c1099
reading very large file sizes as negative numbers.
e7c1099
e7c1099
---
e7c1099
From: Tim Kientzle <kientzle@acm.org>
e7c1099
Date: Fri, 30 Jan 2015 23:57:03 -0800
e7c1099
Subject: [PATCH] Add a check to archive_read_filter_consume to
e7c1099
    reject any attempts to move the file pointer by a negative
e7c1099
    amount.
e7c1099
e7c1099
Note:  Either this or commit 3865cf2 provides a fix for
e7c1099
Issue 394.
e7c1099
e7c1099
---
e7c1099
From: Tim Kientzle <kientzle@acm.org>
e7c1099
Date: Fri, 6 Feb 2015 22:07:16 -0800
e7c1099
Subject: [PATCH] Set a proper error message if we hit end-of-file
e7c1099
    when trying to read a cpio header.
e7c1099
e7c1099
Suggested by Issue #395, although the actual problem there
e7c1099
seems to have been the same as Issue #394.
e7c1099
---
e7c1099
 libarchive/archive_read.c                     |  2 ++
e7c1099
 libarchive/archive_read_support_format_cpio.c | 22 ++++++++++++++--------
e7c1099
 2 files changed, 16 insertions(+), 8 deletions(-)
e7c1099
e7c1099
diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
e7c1099
index 048c316..7f3edc1 100644
e7c1099
--- a/libarchive/archive_read.c
e7c1099
+++ b/libarchive/archive_read.c
e7c1099
@@ -1394,6 +1394,8 @@ __archive_read_filter_consume(struct archive_read_filter * filter,
e7c1099
 {
e7c1099
 	int64_t skipped;
e7c1099
 
e7c1099
+	if (request < 0)
e7c1099
+		return ARCHIVE_FATAL;
e7c1099
 	if (request == 0)
e7c1099
 		return 0;
e7c1099
 
e7c1099
diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
e7c1099
index 819f4a4..1dabc47 100644
e7c1099
--- a/libarchive/archive_read_support_format_cpio.c
e7c1099
+++ b/libarchive/archive_read_support_format_cpio.c
e7c1099
@@ -198,7 +198,7 @@ static int	archive_read_format_cpio_read_data(struct archive_read *,
e7c1099
 static int	archive_read_format_cpio_read_header(struct archive_read *,
e7c1099
 		    struct archive_entry *);
e7c1099
 static int	archive_read_format_cpio_skip(struct archive_read *);
e7c1099
-static int	be4(const unsigned char *);
e7c1099
+static int64_t	be4(const unsigned char *);
e7c1099
 static int	find_odc_header(struct archive_read *);
e7c1099
 static int	find_newc_header(struct archive_read *);
e7c1099
 static int	header_bin_be(struct archive_read *, struct cpio *,
e7c1099
@@ -213,7 +213,7 @@ static int	header_afiol(struct archive_read *, struct cpio *,
e7c1099
 		    struct archive_entry *, size_t *, size_t *);
e7c1099
 static int	is_octal(const char *, size_t);
e7c1099
 static int	is_hex(const char *, size_t);
e7c1099
-static int	le4(const unsigned char *);
e7c1099
+static int64_t	le4(const unsigned char *);
e7c1099
 static int	record_hardlink(struct archive_read *a,
e7c1099
 		    struct cpio *cpio, struct archive_entry *entry);
e7c1099
 
e7c1099
@@ -864,8 +864,11 @@ header_bin_le(struct archive_read *a, struct cpio *cpio,
e7c1099
 
e7c1099
 	/* Read fixed-size portion of header. */
e7c1099
 	h = __archive_read_ahead(a, bin_header_size, NULL);
e7c1099
-	if (h == NULL)
e7c1099
+	if (h == NULL) {
e7c1099
+	    archive_set_error(&a->archive, 0,
e7c1099
+		"End of file trying to read next cpio header");
e7c1099
 	    return (ARCHIVE_FATAL);
e7c1099
+	}
e7c1099
 
e7c1099
 	/* Parse out binary fields. */
e7c1099
 	header = (const unsigned char *)h;
e7c1099
@@ -900,8 +903,11 @@ header_bin_be(struct archive_read *a, struct cpio *cpio,
e7c1099
 
e7c1099
 	/* Read fixed-size portion of header. */
e7c1099
 	h = __archive_read_ahead(a, bin_header_size, NULL);
e7c1099
-	if (h == NULL)
e7c1099
+	if (h == NULL) {
e7c1099
+	    archive_set_error(&a->archive, 0,
e7c1099
+		"End of file trying to read next cpio header");
e7c1099
 	    return (ARCHIVE_FATAL);
e7c1099
+	}
e7c1099
 
e7c1099
 	/* Parse out binary fields. */
e7c1099
 	header = (const unsigned char *)h;
e7c1099
@@ -944,17 +950,17 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
e7c1099
 	return (ARCHIVE_OK);
e7c1099
 }
e7c1099
 
e7c1099
-static int
e7c1099
+static int64_t
e7c1099
 le4(const unsigned char *p)
e7c1099
 {
e7c1099
-	return ((p[0]<<16) + (p[1]<<24) + (p[2]<<0) + (p[3]<<8));
e7c1099
+	return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8));
e7c1099
 }
e7c1099
 
e7c1099
 
e7c1099
-static int
e7c1099
+static int64_t
e7c1099
 be4(const unsigned char *p)
e7c1099
 {
e7c1099
-	return ((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + (p[3]));
e7c1099
+	return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]));
e7c1099
 }
e7c1099
 
e7c1099
 /*
e7c1099
-- 
e7c1099
2.1.0
e7c1099