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

Commit cae99c43 authored by Yifan Hong's avatar Yifan Hong Committed by Gerrit Code Review
Browse files

Merge "Delete VINTF compatibility check during OTA."

parents b12e54c4 c77bb701
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ cc_defaults {
        "libsnapshot_nobinder",

        // external dependencies
        "libvintf_recovery",
        "libvintf",
    ],
}
+0 −4
Original line number Diff line number Diff line
@@ -59,10 +59,6 @@ bool verify_package(Package* package, RecoveryUI* ui);
// result to |metadata|. Return true if succeed, otherwise return false.
bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::string>* metadata);

// Verifies the compatibility info in a Treble-compatible package. Returns true directly if the
// entry doesn't exist.
bool verify_package_compatibility(ZipArchiveHandle package_zip);

// Checks if the metadata in the OTA package has expected values. Mandatory checks: ota-type,
// pre-device and serial number (if presents). A/B OTA specific checks: pre-build version,
// fingerprint, timestamp.
+0 −81
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <vintf/VintfObjectRecovery.h>

#include "install/package.h"
#include "install/verifier.h"
@@ -505,73 +504,6 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache,
  return INSTALL_SUCCESS;
}

// Verifies the compatibility info in a Treble-compatible package. Returns true directly if the
// entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
// package.
bool verify_package_compatibility(ZipArchiveHandle package_zip) {
  LOG(INFO) << "Verifying package compatibility...";

  static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip";
  ZipEntry compatibility_entry;
  if (FindEntry(package_zip, COMPATIBILITY_ZIP_ENTRY, &compatibility_entry) != 0) {
    LOG(INFO) << "Package doesn't contain " << COMPATIBILITY_ZIP_ENTRY << " entry";
    return true;
  }

  std::string zip_content(compatibility_entry.uncompressed_length, '\0');
  int32_t ret;
  if ((ret = ExtractToMemory(package_zip, &compatibility_entry,
                             reinterpret_cast<uint8_t*>(&zip_content[0]),
                             compatibility_entry.uncompressed_length)) != 0) {
    LOG(ERROR) << "Failed to read " << COMPATIBILITY_ZIP_ENTRY << ": " << ErrorCodeString(ret);
    return false;
  }

  ZipArchiveHandle zip_handle;
  ret = OpenArchiveFromMemory(static_cast<void*>(const_cast<char*>(zip_content.data())),
                              zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle);
  if (ret != 0) {
    LOG(ERROR) << "Failed to OpenArchiveFromMemory: " << ErrorCodeString(ret);
    return false;
  }

  // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents.
  void* cookie;
  ret = StartIteration(zip_handle, &cookie);
  if (ret != 0) {
    LOG(ERROR) << "Failed to start iterating zip entries: " << ErrorCodeString(ret);
    CloseArchive(zip_handle);
    return false;
  }
  std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);

  std::vector<std::string> compatibility_info;
  ZipEntry info_entry;
  std::string_view info_name;
  while (Next(cookie, &info_entry, &info_name) == 0) {
    std::string content(info_entry.uncompressed_length, '\0');
    int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
                                  info_entry.uncompressed_length);
    if (ret != 0) {
      LOG(ERROR) << "Failed to read " << info_name << ": " << ErrorCodeString(ret);
      CloseArchive(zip_handle);
      return false;
    }
    compatibility_info.emplace_back(std::move(content));
  }
  CloseArchive(zip_handle);

  // VintfObjectRecovery::CheckCompatibility returns zero on success.
  std::string err;
  int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
  if (result == 0) {
    return true;
  }

  LOG(ERROR) << "Failed to verify package compatibility (result " << result << "): " << err;
  return false;
}

static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache,
                                             std::vector<std::string>* log_buffer, int retry_count,
                                             int* max_temperature, RecoveryUI* ui) {
@@ -586,19 +518,6 @@ static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache,
    return INSTALL_CORRUPT;
  }

  // Try to open the package.
  ZipArchiveHandle zip = package->GetZipArchiveHandle();
  if (!zip) {
    log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));
    return INSTALL_CORRUPT;
  }

  // Additionally verify the compatibility of the package if it's a fresh install.
  if (retry_count == 0 && !verify_package_compatibility(zip)) {
    log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));
    return INSTALL_CORRUPT;
  }

  // Verify and install the contents of the package.
  ui->Print("Installing update...\n");
  if (retry_count > 0) {
+0 −1
Original line number Diff line number Diff line
@@ -81,7 +81,6 @@ librecovery_static_libs = [
    "libotautil",

    "libhealthhalutils",
    "libvintf_recovery",
    "libvintf",

    "android.hardware.health@2.0",
+0 −82
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <gtest/gtest.h>
#include <vintf/VintfObjectRecovery.h>
#include <ziparchive/zip_archive.h>
#include <ziparchive/zip_writer.h>

@@ -50,29 +49,6 @@ static void BuildZipArchive(const std::map<std::string, std::string>& file_map,
  ASSERT_EQ(0, fclose(zip_file));
}

TEST(InstallTest, verify_package_compatibility_no_entry) {
  TemporaryFile temp_file;
  // The archive must have something to be opened correctly.
  BuildZipArchive({ { "dummy_entry", "" } }, temp_file.release(), kCompressStored);

  // Doesn't contain compatibility zip entry.
  ZipArchiveHandle zip;
  ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
  ASSERT_TRUE(verify_package_compatibility(zip));
  CloseArchive(zip);
}

TEST(InstallTest, verify_package_compatibility_invalid_entry) {
  TemporaryFile temp_file;
  BuildZipArchive({ { "compatibility.zip", "" } }, temp_file.release(), kCompressStored);

  // Empty compatibility zip entry.
  ZipArchiveHandle zip;
  ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
  ASSERT_FALSE(verify_package_compatibility(zip));
  CloseArchive(zip);
}

TEST(InstallTest, read_metadata_from_package_smoke) {
  TemporaryFile temp_file;
  const std::string content("abc=defg");
@@ -134,64 +110,6 @@ TEST(InstallTest, read_wipe_ab_partition_list) {
  ASSERT_EQ(expected, read_partition_list);
}

TEST(InstallTest, verify_package_compatibility_with_libvintf_malformed_xml) {
  TemporaryFile compatibility_zip_file;
  std::string malformed_xml = "malformed";
  BuildZipArchive({ { "system_manifest.xml", malformed_xml } }, compatibility_zip_file.release(),
                  kCompressDeflated);

  TemporaryFile temp_file;
  std::string compatibility_zip_content;
  ASSERT_TRUE(
      android::base::ReadFileToString(compatibility_zip_file.path, &compatibility_zip_content));
  BuildZipArchive({ { "compatibility.zip", compatibility_zip_content } }, temp_file.release(),
                  kCompressStored);

  ZipArchiveHandle zip;
  ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
  std::vector<std::string> compatibility_info;
  compatibility_info.push_back(malformed_xml);
  // Malformed compatibility zip is expected to be rejected by libvintf. But we defer that to
  // libvintf.
  std::string err;
  bool result =
      android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err) == 0;
  ASSERT_EQ(result, verify_package_compatibility(zip));
  CloseArchive(zip);
}

TEST(InstallTest, verify_package_compatibility_with_libvintf_system_manifest_xml) {
  static constexpr const char* system_manifest_xml_path = "/system/manifest.xml";
  if (access(system_manifest_xml_path, R_OK) == -1) {
    GTEST_LOG_(INFO) << "Test skipped on devices w/o /system/manifest.xml.";
    return;
  }
  std::string system_manifest_xml_content;
  ASSERT_TRUE(
      android::base::ReadFileToString(system_manifest_xml_path, &system_manifest_xml_content));
  TemporaryFile compatibility_zip_file;
  BuildZipArchive({ { "system_manifest.xml", system_manifest_xml_content } },
                  compatibility_zip_file.release(), kCompressDeflated);

  TemporaryFile temp_file;
  std::string compatibility_zip_content;
  ASSERT_TRUE(
      android::base::ReadFileToString(compatibility_zip_file.path, &compatibility_zip_content));
  BuildZipArchive({ { "compatibility.zip", compatibility_zip_content } }, temp_file.release(),
                  kCompressStored);

  ZipArchiveHandle zip;
  ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
  std::vector<std::string> compatibility_info;
  compatibility_info.push_back(system_manifest_xml_content);
  std::string err;
  bool result =
      android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err) == 0;
  // Make sure the result is consistent with libvintf library.
  ASSERT_EQ(result, verify_package_compatibility(zip));
  CloseArchive(zip);
}

TEST(InstallTest, SetUpNonAbUpdateCommands) {
  TemporaryFile temp_file;
  static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";