diff options
author | Tim Kientzle <kientzle@acm.org> | 2015-07-26 17:09:22 -0700 |
---|---|---|
committer | Tim Kientzle <kientzle@acm.org> | 2015-07-26 17:09:22 -0700 |
commit | 3c7a6dc6694d9b26400d2bd672e04d09ed8a4276 (patch) | |
tree | ab49cea050db41889878618649349854ec551047 /libarchive/archive_read_support_format_tar.c | |
parent | 237eb9550368a0f4cf6a75fd907de4cbe78e7168 (diff) | |
download | libarchive-3c7a6dc6694d9b26400d2bd672e04d09ed8a4276.tar.gz |
Issue #582: reject sparse blocks with negative size or offset, detect overflow when tracking sparse blocks
Diffstat (limited to 'libarchive/archive_read_support_format_tar.c')
-rw-r--r-- | libarchive/archive_read_support_format_tar.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c index 1e780936..01d85cf6 100644 --- a/libarchive/archive_read_support_format_tar.c +++ b/libarchive/archive_read_support_format_tar.c @@ -604,8 +604,12 @@ archive_read_format_tar_skip(struct archive_read *a) /* Do not consume the hole of a sparse file. */ request = 0; for (p = tar->sparse_list; p != NULL; p = p->next) { - if (!p->hole) + if (!p->hole) { + if (p->remaining >= INT64_MAX - request) { + return ARCHIVE_FATAL; + } request += p->remaining; + } } if (request > tar->entry_bytes_remaining) request = tar->entry_bytes_remaining; @@ -2123,6 +2127,10 @@ gnu_add_sparse_entry(struct archive_read *a, struct tar *tar, else tar->sparse_list = p; tar->sparse_last = p; + if (remaining < 0 || offset < 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data"); + return (ARCHIVE_FATAL); + } p->offset = offset; p->remaining = remaining; return (ARCHIVE_OK); |