summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_read_support_format_iso9660.c
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2011-08-07 08:42:36 +0000
committermm <mm@FreeBSD.org>2011-08-07 08:42:36 +0000
commit85a8d1da23a1394d897113a90cf44951d98b33b3 (patch)
tree12a90ffe66bb9ed1a58c1de3799b1d16a5ae2126 /lib/libarchive/archive_read_support_format_iso9660.c
parent6a47448a9e4ed26220b7dc7f31976c4367152d2e (diff)
downloadFreeBSD-src-85a8d1da23a1394d897113a90cf44951d98b33b3.zip
FreeBSD-src-85a8d1da23a1394d897113a90cf44951d98b33b3.tar.gz
Add compatibility for ISO images created with unfixed makefs that
violated ECMA-119 (ISO9660): allow reserved4 to be 0x20 in PVD. This allows tar to read FreeBSD distribution ISO images created with makefs prior to NetBSD bin/45217 bugfix (up to 9.0-BETA1). In addition, merge following important bugfixes from libarchive's release/2.8 branch: Revision 2812: Merge 2811 from trunk: Don't try to verify that compression-level=0 produces larger results than the default compression, since this isn't true for all versions of liblzma. Revision 2817: Merge 2814 from trunk: Fix Issue 121 (mtree parser error) http://code.google.com/p/libarchive/issues/detail?id=121 Revision 2820: Fix issue 119. Change the file location check that a file location does not exceed volume block. New one is that a file content does not exceed volume block(end of an ISO image). It is better than previous check even if the issue did not happen. While reading an ISO image generated by an older version of mkisofs utility, a file location indicates the end the ISO image if its file size is zero and it is the last file of all files of the ISO image, so it is possible that the location value is the same as the number of the total block of the ISO image. http://code.google.com/p/libarchive/issues/detail?id=119 Revision 2955: Issue 134: Fix libarchive 2.8 crashing in archive_write_finish() when the open has failed and we're trying to write Zip format. http://code.google.com/p/libarchive/issues/detail?id=134 Revision 2958: Followup on Issue 134: 1) Port test_open_failure to libarchive 2.8 branch to test the problem reported in Issue 134. This test also shows that archive_read_open() sometimes fails to report open errors correctly. 2) Fix the bug in archive_read.c 3) Comment out the tests that close functions are invoked promptly when open fails; that's fully fixed in libarchive 3.0, but I don't think it's worth fixing here. Revision 3484: Use uintmax_t with %ju Revision 3487: Fix issue 163. Correctly allocate enough memory for a input buffer saved. http://code.google.com/p/libarchive/issues/detail?id=163 Revision 3542: Merge 2516, 2536 from trunk: Allow path table offset values of 0 and 18, which are used by some ISO writers. Reviewed by: kientzle Approved by: re (kib) MFC after: 3 days
Diffstat (limited to 'lib/libarchive/archive_read_support_format_iso9660.c')
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c
index 1f64003..2cca410 100644
--- a/lib/libarchive/archive_read_support_format_iso9660.c
+++ b/lib/libarchive/archive_read_support_format_iso9660.c
@@ -709,16 +709,18 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
/* Location of Occurrence of Type L Path Table must be
* available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_le32dec(h+SVD_type_L_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
return (0);
- /* Location of Occurrence of Type M Path Table must be
- * available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ /* The Type M Path Table must be at a valid location (WinISO
+ * and probably other programs omit this, so we allow zero)
+ *
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_be32dec(h+SVD_type_M_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
return (0);
/* Read Root Directory Record in Volume Descriptor. */
@@ -781,16 +783,17 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
/* Location of Occurrence of Type L Path Table must be
* available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_le32dec(h+PVD_type_1_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
return (0);
/* Location of Occurrence of Type M Path Table must be
* available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_be32dec(h+PVD_type_m_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
return (0);
/* Reserved field must be 0. */
@@ -862,19 +865,24 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
* available location,
* > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_le32dec(h+PVD_type_1_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
return (0);
- /* Location of Occurrence of Type M Path Table must be
- * available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ /* The Type M Path Table must also be at a valid location
+ * (although ECMA 119 requires a Type M Path Table, WinISO and
+ * probably other programs omit it, so we permit a zero here)
+ *
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_be32dec(h+PVD_type_m_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
return (0);
/* Reserved field must be 0. */
+ /* FreeBSD: makefs erroneously created images with 0x20 */
for (i = 0; i < PVD_reserved4_size; ++i)
- if (h[PVD_reserved4_offset + i] != 0)
+ if (h[PVD_reserved4_offset + i] != 0 &&
+ h[PVD_reserved4_offset + i] != 32)
return (0);
/* Reserved field must be 0. */
@@ -1677,6 +1685,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
const unsigned char *rr_start, *rr_end;
const unsigned char *p;
size_t dr_len;
+ uint64_t fsize;
int32_t location;
int flags;
@@ -1685,6 +1694,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
dr_len = (size_t)isodirrec[DR_length_offset];
name_len = (size_t)isodirrec[DR_name_len_offset];
location = archive_le32dec(isodirrec + DR_extent_offset);
+ fsize = toi(isodirrec + DR_size_offset, DR_size_size);
/* Sanity check that dr_len needs at least 34. */
if (dr_len < 34) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1703,7 +1713,10 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* link or file size is zero. As far as I know latest mkisofs
* do that.
*/
- if (location >= iso9660->volume_block) {
+ if (location > 0 &&
+ (location + ((fsize + iso9660->logical_block_size -1)
+ / iso9660->logical_block_size)) >
+ (unsigned int)iso9660->volume_block) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Invalid location of extent of file");
return (NULL);
@@ -1719,7 +1732,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
memset(file, 0, sizeof(*file));
file->parent = parent;
file->offset = iso9660->logical_block_size * (uint64_t)location;
- file->size = toi(isodirrec + DR_size_offset, DR_size_size);
+ file->size = fsize;
file->mtime = isodate7(isodirrec + DR_date_offset);
file->ctime = file->atime = file->mtime;
OpenPOWER on IntegriCloud