summaryrefslogtreecommitdiff
path: root/libarchive/archive_read_support_format_tar.c
diff options
context:
space:
mode:
authorMartin Matuska <martin@matuska.org>2017-02-17 22:31:16 +0100
committerMartin Matuska <martin@matuska.org>2017-02-17 22:34:48 +0100
commitc4d3694f7164c966611ac8a07c22219aefab4d63 (patch)
treec70667c1e7d44c71476f2c340ee40d9aeb092e73 /libarchive/archive_read_support_format_tar.c
parent0edabbad1f44641c64fe9d0cbaed27ed93ab38c2 (diff)
downloadlibarchive-c4d3694f7164c966611ac8a07c22219aefab4d63.tar.gz
tar reader: fail if negative entry_bytes_remaining in gnu_sparse_10_read()
Do not subtract error value from entry_bytes_remaining in tar_read_header() Fixes #864
Diffstat (limited to 'libarchive/archive_read_support_format_tar.c')
-rw-r--r--libarchive/archive_read_support_format_tar.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index bc4ba3db..bd7f13d5 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -847,9 +847,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
tar->sparse_gnu_pending = 0;
/* Read initial sparse map. */
bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
- tar->entry_bytes_remaining -= bytes_read;
if (bytes_read < 0)
return ((int)bytes_read);
+ tar->entry_bytes_remaining -= bytes_read;
} else {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
@@ -2487,6 +2487,9 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
tar_flush_unconsumed(a, unconsumed);
bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
to_skip = 0x1ff & -bytes_read;
+ /* Fail if tar->entry_bytes_remaing would get negative */
+ if (to_skip > remaining)
+ return (ARCHIVE_FATAL);
if (to_skip != __archive_read_consume(a, to_skip))
return (ARCHIVE_FATAL);
return ((ssize_t)(bytes_read + to_skip));