system/core
修訂 | 9a0048e52980b3ba14a4ebe16468a9d899f47323 (tree) |
---|---|
時間 | 2017-10-20 05:01:44 |
作者 | Narayan Kamath <narayan@goog...> |
Commiter | JP Sugarbroad |
zip_archive: reject files that don't start with an LFH signature.
Bug: 64211847
Test: zip_archive_test
Merged-In: Ib89f0def696206ff427be27764c158fab88e4b5d
Merged-In: I275e7c4da05ceeb20401b560c72294f29ef63642
Change-Id: I38705f4e9688326a140aa59a1333b0878ed39c14
(cherry picked from commit 2740bb09e3cee99032a86a1700cb0a6f14f3a51f)
@@ -358,6 +358,8 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name, | ||
358 | 358 | return result; |
359 | 359 | } |
360 | 360 | |
361 | +static inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off); | |
362 | + | |
361 | 363 | /* |
362 | 364 | * Parses the Zip archive's Central Directory. Allocates and populates the |
363 | 365 | * hash table. |
@@ -436,6 +438,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) { | ||
436 | 438 | return -1; |
437 | 439 | } |
438 | 440 | } |
441 | + | |
442 | + uint32_t lfh_start_bytes; | |
443 | + if (!ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes), | |
444 | + sizeof(uint32_t), 0)) { | |
445 | + ALOGW("Zip: Unable to read header for entry at offset == 0."); | |
446 | + return -1; | |
447 | + } | |
448 | + | |
449 | + if (lfh_start_bytes != LocalFileHeader::kSignature) { | |
450 | + ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes); | |
451 | +#if defined(__ANDROID__) | |
452 | + android_errorWriteLog(0x534e4554, "64211847"); | |
453 | +#endif | |
454 | + return -1; | |
455 | + } | |
456 | + | |
439 | 457 | ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); |
440 | 458 | |
441 | 459 | return 0; |
@@ -603,6 +603,55 @@ TEST(ziparchive, StreamUncompressedBadCrc) { | ||
603 | 603 | CloseArchive(handle); |
604 | 604 | } |
605 | 605 | |
606 | +// A zip file whose local file header at offset zero is corrupted. | |
607 | +// | |
608 | +// --------------- | |
609 | +// cat foo > a.txt | |
610 | +// zip a.zip a.txt | |
611 | +// cat a.zip | xxd -i | |
612 | +// | |
613 | +// Manual changes : | |
614 | +// [2] = 0xff // Corrupt the LFH signature of entry 0. | |
615 | +// [3] = 0xff // Corrupt the LFH signature of entry 0. | |
616 | +static const std::vector<uint8_t> kZipFileWithBrokenLfhSignature{ | |
617 | + //[lfh-sig-----------], [lfh contents--------------------------------- | |
618 | + 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, | |
619 | + //-------------------------------------------------------------------- | |
620 | + 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, | |
621 | + //-------------------------------] [file-name-----------------], [--- | |
622 | + 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, | |
623 | + // entry-contents------------------------------------------------------ | |
624 | + 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59, | |
625 | + //-------------------------------------------------------------------- | |
626 | + 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, | |
627 | + //-------------------------------------], [cd-record-sig-------], [--- | |
628 | + 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, | |
629 | + // cd-record----------------------------------------------------------- | |
630 | + 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8, | |
631 | + //-------------------------------------------------------------------- | |
632 | + 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, | |
633 | + //-------------------------------------------------------------------- | |
634 | + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, | |
635 | + //-] [lfh-file-header-off-], [file-name-----------------], [extra---- | |
636 | + 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, | |
637 | + //-------------------------------------------------------------------- | |
638 | + 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01, | |
639 | + //-------------------------------------------------------], [eocd-sig- | |
640 | + 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b, | |
641 | + //-------], [--------------------------------------------------------- | |
642 | + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00, | |
643 | + //-------------------------------------------] | |
644 | + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
645 | + | |
646 | +TEST(ziparchive, BrokenLfhSignature) { | |
647 | + TemporaryFile tmp_file; | |
648 | + ASSERT_NE(-1, tmp_file.fd); | |
649 | + ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], | |
650 | + kZipFileWithBrokenLfhSignature.size())); | |
651 | + ZipArchiveHandle handle; | |
652 | + ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); | |
653 | +} | |
654 | + | |
606 | 655 | int main(int argc, char** argv) { |
607 | 656 | ::testing::InitGoogleTest(&argc, argv); |
608 | 657 |