Loading libziparchive/zip_archive.cc +18 −0 Original line number Original line Diff line number Diff line Loading @@ -552,6 +552,8 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name, return result; return result; } } static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off); /* /* * Parses the Zip archive's Central Directory. Allocates and populates the * Parses the Zip archive's Central Directory. Allocates and populates the * hash table. * hash table. Loading Loading @@ -630,6 +632,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) { return -1; return -1; } } } } uint32_t lfh_start_bytes; if (ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes), sizeof(uint32_t), 0) != sizeof(uint32_t)) { ALOGW("Zip: Unable to read header for entry at offset == 0."); return -1; } if (lfh_start_bytes != LocalFileHeader::kSignature) { ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes); #if defined(__ANDROID__) android_errorWriteLog(0x534e4554, "64211847"); #endif return -1; } ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); return 0; return 0; Loading libziparchive/zip_archive_test.cc +49 −0 Original line number Original line Diff line number Diff line Loading @@ -530,6 +530,55 @@ TEST(ziparchive, ExtractToFile) { close(fd); close(fd); } } // A zip file whose local file header at offset zero is corrupted. // // --------------- // cat foo > a.txt // zip a.zip a.txt // cat a.zip | xxd -i // // Manual changes : // [2] = 0xff // Corrupt the LFH signature of entry 0. // [3] = 0xff // Corrupt the LFH signature of entry 0. static const std::vector<uint8_t> kZipFileWithBrokenLfhSignature{ //[lfh-sig-----------], [lfh contents--------------------------------- 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, //-------------------------------------------------------------------- 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, //-------------------------------] [file-name-----------------], [--- 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, // entry-contents------------------------------------------------------ 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59, //-------------------------------------------------------------------- 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, //-------------------------------------], [cd-record-sig-------], [--- 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, // cd-record----------------------------------------------------------- 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8, //-------------------------------------------------------------------- 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, //-------------------------------------------------------------------- 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, //-] [lfh-file-header-off-], [file-name-----------------], [extra---- 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, //-------------------------------------------------------------------- 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01, //-------------------------------------------------------], [eocd-sig- 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b, //-------], [--------------------------------------------------------- 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00, //-------------------------------------------] 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; TEST(ziparchive, BrokenLfhSignature) { TemporaryFile tmp_file; ASSERT_NE(-1, tmp_file.fd); ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], kZipFileWithBrokenLfhSignature.size())); ZipArchiveHandle handle; ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); } int main(int argc, char** argv) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv); Loading Loading
libziparchive/zip_archive.cc +18 −0 Original line number Original line Diff line number Diff line Loading @@ -552,6 +552,8 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name, return result; return result; } } static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off); /* /* * Parses the Zip archive's Central Directory. Allocates and populates the * Parses the Zip archive's Central Directory. Allocates and populates the * hash table. * hash table. Loading Loading @@ -630,6 +632,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) { return -1; return -1; } } } } uint32_t lfh_start_bytes; if (ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes), sizeof(uint32_t), 0) != sizeof(uint32_t)) { ALOGW("Zip: Unable to read header for entry at offset == 0."); return -1; } if (lfh_start_bytes != LocalFileHeader::kSignature) { ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes); #if defined(__ANDROID__) android_errorWriteLog(0x534e4554, "64211847"); #endif return -1; } ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); return 0; return 0; Loading
libziparchive/zip_archive_test.cc +49 −0 Original line number Original line Diff line number Diff line Loading @@ -530,6 +530,55 @@ TEST(ziparchive, ExtractToFile) { close(fd); close(fd); } } // A zip file whose local file header at offset zero is corrupted. // // --------------- // cat foo > a.txt // zip a.zip a.txt // cat a.zip | xxd -i // // Manual changes : // [2] = 0xff // Corrupt the LFH signature of entry 0. // [3] = 0xff // Corrupt the LFH signature of entry 0. static const std::vector<uint8_t> kZipFileWithBrokenLfhSignature{ //[lfh-sig-----------], [lfh contents--------------------------------- 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, //-------------------------------------------------------------------- 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, //-------------------------------] [file-name-----------------], [--- 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, // entry-contents------------------------------------------------------ 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59, //-------------------------------------------------------------------- 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, //-------------------------------------], [cd-record-sig-------], [--- 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, // cd-record----------------------------------------------------------- 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8, //-------------------------------------------------------------------- 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, //-------------------------------------------------------------------- 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, //-] [lfh-file-header-off-], [file-name-----------------], [extra---- 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, //-------------------------------------------------------------------- 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01, //-------------------------------------------------------], [eocd-sig- 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b, //-------], [--------------------------------------------------------- 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00, //-------------------------------------------] 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; TEST(ziparchive, BrokenLfhSignature) { TemporaryFile tmp_file; ASSERT_NE(-1, tmp_file.fd); ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], kZipFileWithBrokenLfhSignature.size())); ZipArchiveHandle handle; ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); } int main(int argc, char** argv) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv); Loading