diff options
author | Tim Kientzle <kientzle@gmail.com> | 2008-05-20 15:57:10 -0400 |
---|---|---|
committer | Tim Kientzle <kientzle@gmail.com> | 2008-05-20 15:57:10 -0400 |
commit | 28bffcb0cf9a34f46f12cdda79fc9b3973c0a0ec (patch) | |
tree | 10f7ee7ab487ce1c3fefcd157cc8186c71c129b2 /libarchive/archive_read_support_format_ar.c | |
parent | d9363627f065141107726b61173d67e6df3c5d94 (diff) | |
download | libarchive-28bffcb0cf9a34f46f12cdda79fc9b3973c0a0ec.tar.gz |
Guard against a number of theoretical buffer and integer
overflows. As far as I can tell, none of these are
actually exploitable.
Thanks to David Remahl at Apple for pointing these out.
MFP4 after: 1 day
SVN-Revision: 77
Diffstat (limited to 'libarchive/archive_read_support_format_ar.c')
-rw-r--r-- | libarchive/archive_read_support_format_ar.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c index f6e4cc7e..846b4ad9 100644 --- a/libarchive/archive_read_support_format_ar.c +++ b/libarchive/archive_read_support_format_ar.c @@ -350,12 +350,16 @@ archive_read_format_ar_read_header(struct archive_read *a, /* Parse the size of the name, adjust the file size. */ number = ar_atol10(h + AR_name_offset + 3, AR_name_size - 3); - if ((off_t)number > ar->entry_bytes_remaining) { + bsd_name_length = (size_t)number; + /* Guard against the filename + trailing NUL + * overflowing a size_t and against the filename size + * being larger than the entire entry. */ + if (number > (uint64_t)(bsd_name_length + 1) + || (uint64_t)bsd_name_length > ar->entry_bytes_remaining) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Bad input file size"); return (ARCHIVE_FATAL); } - bsd_name_length = (size_t)number; ar->entry_bytes_remaining -= bsd_name_length; /* Adjust file size reported to client. */ archive_entry_set_size(entry, ar->entry_bytes_remaining); |