Verify the package compatibility with libvintf.
am: 62e0bc7586
Change-Id: I35383abfd52766070df0de00013ec743dea190c7
This commit is contained in:
24
Android.mk
24
Android.mk
@@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
# Needed by build/make/core/Makefile.
|
||||||
|
RECOVERY_API_VERSION := 3
|
||||||
|
RECOVERY_FSTAB_VERSION := 2
|
||||||
|
|
||||||
# libfusesideload (static library)
|
# libfusesideload (static library)
|
||||||
# ===============================
|
# ===============================
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
@@ -36,6 +40,22 @@ LOCAL_MODULE := libmounts
|
|||||||
LOCAL_STATIC_LIBRARIES := libbase
|
LOCAL_STATIC_LIBRARIES := libbase
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
# librecovery (static library)
|
||||||
|
# ===============================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
install.cpp
|
||||||
|
LOCAL_CFLAGS := -Wno-unused-parameter -Werror
|
||||||
|
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
|
||||||
|
LOCAL_MODULE := librecovery
|
||||||
|
LOCAL_STATIC_LIBRARIES := \
|
||||||
|
libminui \
|
||||||
|
libcrypto_utils \
|
||||||
|
libcrypto \
|
||||||
|
libbase
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
# recovery (static executable)
|
# recovery (static executable)
|
||||||
# ===============================
|
# ===============================
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
@@ -45,7 +65,6 @@ LOCAL_SRC_FILES := \
|
|||||||
asn1_decoder.cpp \
|
asn1_decoder.cpp \
|
||||||
device.cpp \
|
device.cpp \
|
||||||
fuse_sdcard_provider.cpp \
|
fuse_sdcard_provider.cpp \
|
||||||
install.cpp \
|
|
||||||
recovery.cpp \
|
recovery.cpp \
|
||||||
roots.cpp \
|
roots.cpp \
|
||||||
rotate_logs.cpp \
|
rotate_logs.cpp \
|
||||||
@@ -65,8 +84,6 @@ LOCAL_REQUIRED_MODULES := mkfs.f2fs
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RECOVERY_API_VERSION := 3
|
|
||||||
RECOVERY_FSTAB_VERSION := 2
|
|
||||||
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
|
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
|
||||||
LOCAL_CFLAGS += -Wno-unused-parameter -Werror
|
LOCAL_CFLAGS += -Wno-unused-parameter -Werror
|
||||||
LOCAL_CLANG := true
|
LOCAL_CLANG := true
|
||||||
@@ -76,6 +93,7 @@ LOCAL_C_INCLUDES += \
|
|||||||
system/core/adb \
|
system/core/adb \
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := \
|
LOCAL_STATIC_LIBRARIES := \
|
||||||
|
librecovery \
|
||||||
libbatterymonitor \
|
libbatterymonitor \
|
||||||
libbootloader_message \
|
libbootloader_message \
|
||||||
libext4_utils \
|
libext4_utils \
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ enum ErrorCode {
|
|||||||
kLowBattery = 20,
|
kLowBattery = 20,
|
||||||
kZipVerificationFailure,
|
kZipVerificationFailure,
|
||||||
kZipOpenFailure,
|
kZipOpenFailure,
|
||||||
kBootreasonInBlacklist
|
kBootreasonInBlacklist,
|
||||||
|
kPackageCompatibilityFailure,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CauseCode {
|
enum CauseCode {
|
||||||
|
|||||||
73
install.cpp
73
install.cpp
@@ -489,6 +489,70 @@ static int try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_
|
|||||||
return INSTALL_SUCCESS;
|
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
|
static int
|
||||||
really_install_package(const char *path, bool* wipe_cache, bool needs_mount,
|
really_install_package(const char *path, bool* wipe_cache, bool needs_mount,
|
||||||
std::vector<std::string>& log_buffer, int retry_count, int* max_temperature)
|
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;
|
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.
|
// Verify and install the contents of the package.
|
||||||
ui->Print("Installing update...\n");
|
ui->Print("Installing update...\n");
|
||||||
if (retry_count > 0) {
|
if (retry_count > 0) {
|
||||||
|
|||||||
@@ -37,4 +37,8 @@ bool verify_package(const unsigned char* package_data, size_t package_size);
|
|||||||
// Return true if succeed, otherwise return false.
|
// Return true if succeed, otherwise return false.
|
||||||
bool read_metadata_from_package(ZipArchiveHandle zip, std::string* meta_data);
|
bool read_metadata_from_package(ZipArchiveHandle zip, std::string* meta_data);
|
||||||
|
|
||||||
|
// Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
|
||||||
|
// entry doesn't exist.
|
||||||
|
bool verify_package_compatibility(ZipArchiveHandle package_zip);
|
||||||
|
|
||||||
#endif // RECOVERY_INSTALL_H_
|
#endif // RECOVERY_INSTALL_H_
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ LOCAL_SRC_FILES := \
|
|||||||
component/bootloader_message_test.cpp \
|
component/bootloader_message_test.cpp \
|
||||||
component/edify_test.cpp \
|
component/edify_test.cpp \
|
||||||
component/imgdiff_test.cpp \
|
component/imgdiff_test.cpp \
|
||||||
|
component/install_test.cpp \
|
||||||
component/sideload_test.cpp \
|
component/sideload_test.cpp \
|
||||||
component/uncrypt_test.cpp \
|
component/uncrypt_test.cpp \
|
||||||
component/updater_test.cpp \
|
component/updater_test.cpp \
|
||||||
@@ -117,6 +118,7 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libbsdiff \
|
libbsdiff \
|
||||||
libbspatch \
|
libbspatch \
|
||||||
libotafault \
|
libotafault \
|
||||||
|
librecovery \
|
||||||
libupdater \
|
libupdater \
|
||||||
libbootloader_message \
|
libbootloader_message \
|
||||||
libverifier \
|
libverifier \
|
||||||
@@ -131,7 +133,6 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libsparse \
|
libsparse \
|
||||||
libcrypto_utils \
|
libcrypto_utils \
|
||||||
libcrypto \
|
libcrypto \
|
||||||
libcutils \
|
|
||||||
libbz \
|
libbz \
|
||||||
libziparchive \
|
libziparchive \
|
||||||
libutils \
|
libutils \
|
||||||
|
|||||||
57
tests/component/install_test.cpp
Normal file
57
tests/component/install_test.cpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agree to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <android-base/test_utils.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ziparchive/zip_archive.h>
|
||||||
|
#include <ziparchive/zip_writer.h>
|
||||||
|
|
||||||
|
#include "install.h"
|
||||||
|
|
||||||
|
TEST(InstallTest, verify_package_compatibility_no_entry) {
|
||||||
|
TemporaryFile temp_file;
|
||||||
|
FILE* zip_file = fdopen(temp_file.fd, "w");
|
||||||
|
ZipWriter writer(zip_file);
|
||||||
|
// The archive must have something to be opened correctly.
|
||||||
|
ASSERT_EQ(0, writer.StartEntry("dummy_entry", 0));
|
||||||
|
ASSERT_EQ(0, writer.FinishEntry());
|
||||||
|
ASSERT_EQ(0, writer.Finish());
|
||||||
|
ASSERT_EQ(0, fclose(zip_file));
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
FILE* zip_file = fdopen(temp_file.fd, "w");
|
||||||
|
ZipWriter writer(zip_file);
|
||||||
|
ASSERT_EQ(0, writer.StartEntry("compatibility.zip", 0));
|
||||||
|
ASSERT_EQ(0, writer.FinishEntry());
|
||||||
|
ASSERT_EQ(0, writer.Finish());
|
||||||
|
ASSERT_EQ(0, fclose(zip_file));
|
||||||
|
|
||||||
|
// Empty compatibility zip entry.
|
||||||
|
ZipArchiveHandle zip;
|
||||||
|
ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
|
||||||
|
ASSERT_FALSE(verify_package_compatibility(zip));
|
||||||
|
CloseArchive(zip);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user