summaryrefslogtreecommitdiffstats
path: root/install.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'install.cpp')
-rw-r--r--install.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/install.cpp b/install.cpp
index 0a2fa3ca4..b4b869b98 100644
--- a/install.cpp
+++ b/install.cpp
@@ -489,6 +489,70 @@ static int try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_
return INSTALL_SUCCESS;
}
+// Verifes 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";
+ ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY);
+ ZipEntry compatibility_entry;
+ if (FindEntry(package_zip, compatibility_entry_name, &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, nullptr, nullptr);
+ 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;
+ ZipString 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.name << ": " << ErrorCodeString(ret);
+ CloseArchive(zip_handle);
+ return false;
+ }
+ compatibility_info.emplace_back(std::move(content));
+ }
+ EndIteration(cookie);
+ CloseArchive(zip_handle);
+
+ // TODO(b/36814503): Enable the actual verification when VintfObject::CheckCompatibility() lands.
+ // VintfObject::CheckCompatibility returns zero on success.
+ // return (android::vintf::VintfObject::CheckCompatibility(compatibility_info, true) == 0);
+ return true;
+}
+
static int
really_install_package(const char *path, bool* wipe_cache, bool needs_mount,
std::vector<std::string>& log_buffer, int retry_count, int* max_temperature)
@@ -536,6 +600,15 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount,
return INSTALL_CORRUPT;
}
+ // Additionally verify the compatibility of the package.
+ if (!verify_package_compatibility(zip)) {
+ LOG(ERROR) << "Failed to verify package compatibility";
+ log_buffer.push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));
+ sysReleaseMap(&map);
+ CloseArchive(zip);
+ return INSTALL_CORRUPT;
+ }
+
// Verify and install the contents of the package.
ui->Print("Installing update...\n");
if (retry_count > 0) {