Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 368ec42f authored by Narayan Kamath's avatar Narayan Kamath Committed by android-build-merger
Browse files

zip_archive: reject files that don't start with an LFH signature.

am: dbacd826

Change-Id: I85664bba898d6be9fff53bc3514c44df4be6cfc7
parents 33abf909 dbacd826
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -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.
@@ -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;
+49 −0
Original line number Original line Diff line number Diff line
@@ -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);