summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk29
-rw-r--r--error_code.h3
-rw-r--r--etc/init.rc3
-rw-r--r--install.cpp72
-rw-r--r--install.h4
-rw-r--r--minadbd/minadbd_services.cpp30
-rw-r--r--mounts.cpp17
-rw-r--r--mounts.h4
-rw-r--r--tests/Android.mk3
-rw-r--r--tests/component/install_test.cpp57
10 files changed, 166 insertions, 56 deletions
diff --git a/Android.mk b/Android.mk
index d70101395..9e374de8f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,6 +14,10 @@
LOCAL_PATH := $(call my-dir)
+# Needed by build/make/core/Makefile.
+RECOVERY_API_VERSION := 3
+RECOVERY_FSTAB_VERSION := 2
+
# libfusesideload (static library)
# ===============================
include $(CLEAR_VARS)
@@ -36,6 +40,27 @@ LOCAL_MODULE := libmounts
LOCAL_STATIC_LIBRARIES := libbase
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)
+
+ifeq ($(AB_OTA_UPDATER),true)
+ LOCAL_CFLAGS += -DAB_OTA_UPDATER=1
+endif
+
+LOCAL_MODULE := librecovery
+LOCAL_STATIC_LIBRARIES := \
+ libminui \
+ libcrypto_utils \
+ libcrypto \
+ libbase
+
+include $(BUILD_STATIC_LIBRARY)
+
# recovery (static executable)
# ===============================
include $(CLEAR_VARS)
@@ -45,7 +70,6 @@ LOCAL_SRC_FILES := \
asn1_decoder.cpp \
device.cpp \
fuse_sdcard_provider.cpp \
- install.cpp \
recovery.cpp \
roots.cpp \
rotate_logs.cpp \
@@ -65,8 +89,6 @@ LOCAL_REQUIRED_MODULES := mkfs.f2fs
endif
endif
-RECOVERY_API_VERSION := 3
-RECOVERY_FSTAB_VERSION := 2
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
LOCAL_CFLAGS += -Wno-unused-parameter -Werror
LOCAL_CLANG := true
@@ -76,6 +98,7 @@ LOCAL_C_INCLUDES += \
system/core/adb \
LOCAL_STATIC_LIBRARIES := \
+ librecovery \
libbatterymonitor \
libbootloader_message \
libext4_utils \
diff --git a/error_code.h b/error_code.h
index 5dad6b263..cde4ee6de 100644
--- a/error_code.h
+++ b/error_code.h
@@ -22,7 +22,8 @@ enum ErrorCode {
kLowBattery = 20,
kZipVerificationFailure,
kZipOpenFailure,
- kBootreasonInBlacklist
+ kBootreasonInBlacklist,
+ kPackageCompatibilityFailure,
};
enum CauseCode {
diff --git a/etc/init.rc b/etc/init.rc
index 477e13d5e..2e3c7a739 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -75,9 +75,6 @@ on late-init
trigger early-boot
trigger boot
-on property:sys.powerctl=*
- powerctl ${sys.powerctl}
-
service ueventd /sbin/ueventd
critical
seclabel u:r:ueventd:s0
diff --git a/install.cpp b/install.cpp
index 0a2fa3ca4..6dcd3565e 100644
--- a/install.cpp
+++ b/install.cpp
@@ -489,6 +489,69 @@ 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));
+ }
+ 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 +599,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) {
diff --git a/install.h b/install.h
index 1ec01e817..68f0a8d47 100644
--- a/install.h
+++ b/install.h
@@ -37,4 +37,8 @@ bool verify_package(const unsigned char* package_data, size_t package_size);
// Return true if succeed, otherwise return false.
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_
diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp
index 426d982eb..a6aa321ca 100644
--- a/minadbd/minadbd_services.cpp
+++ b/minadbd/minadbd_services.cpp
@@ -21,25 +21,13 @@
#include <string.h>
#include <unistd.h>
+#include <thread>
+
#include "adb.h"
#include "fdevent.h"
#include "fuse_adb_provider.h"
#include "sysdeps.h"
-typedef struct stinfo stinfo;
-
-struct stinfo {
- void (*func)(int fd, void *cookie);
- int fd;
- void *cookie;
-};
-
-void service_bootstrap_func(void* x) {
- stinfo* sti = reinterpret_cast<stinfo*>(x);
- sti->func(sti->fd, sti->cookie);
- free(sti);
-}
-
static void sideload_host_service(int sfd, void* data) {
char* args = reinterpret_cast<char*>(data);
int file_size;
@@ -66,19 +54,7 @@ static int create_service_thread(void (*func)(int, void *), void *cookie) {
return -1;
}
- stinfo* sti = static_cast<stinfo*>(malloc(sizeof(stinfo)));
- if(sti == 0) fatal("cannot allocate stinfo");
- sti->func = func;
- sti->cookie = cookie;
- sti->fd = s[1];
-
- if (!adb_thread_create(service_bootstrap_func, sti)) {
- free(sti);
- adb_close(s[0]);
- adb_close(s[1]);
- printf("cannot create service thread\n");
- return -1;
- }
+ std::thread([s, func, cookie]() { func(s[1], cookie); }).detach();
VLOG(SERVICES) << "service thread started, " << s[0] << ":" << s[1];
return s[0];
diff --git a/mounts.cpp b/mounts.cpp
index fbcbac014..76fa65739 100644
--- a/mounts.cpp
+++ b/mounts.cpp
@@ -62,13 +62,6 @@ bool scan_mounted_volumes() {
return true;
}
-MountedVolume* find_mounted_volume_by_device(const char* device) {
- for (size_t i = 0; i < g_mounts_state.size(); ++i) {
- if (g_mounts_state[i]->device == device) return g_mounts_state[i];
- }
- return nullptr;
-}
-
MountedVolume* find_mounted_volume_by_mount_point(const char* mount_point) {
for (size_t i = 0; i < g_mounts_state.size(); ++i) {
if (g_mounts_state[i]->mount_point == mount_point) return g_mounts_state[i];
@@ -87,13 +80,3 @@ int unmount_mounted_volume(MountedVolume* volume) {
}
return result;
}
-
-int remount_read_only(MountedVolume* volume) {
- int result = mount(volume->device.c_str(), volume->mount_point.c_str(),
- volume->filesystem.c_str(),
- MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY | MS_REMOUNT, 0);
- if (result == -1) {
- PLOG(WARNING) << "Failed to remount read-only " << volume->mount_point;
- }
- return result;
-}
diff --git a/mounts.h b/mounts.h
index 1b7670329..0de1ebd0a 100644
--- a/mounts.h
+++ b/mounts.h
@@ -21,12 +21,8 @@ struct MountedVolume;
bool scan_mounted_volumes();
-MountedVolume* find_mounted_volume_by_device(const char* device);
-
MountedVolume* find_mounted_volume_by_mount_point(const char* mount_point);
int unmount_mounted_volume(MountedVolume* volume);
-int remount_read_only(MountedVolume* volume);
-
#endif
diff --git a/tests/Android.mk b/tests/Android.mk
index 974aa0e2d..a1f0d4892 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -93,6 +93,7 @@ LOCAL_SRC_FILES := \
component/bootloader_message_test.cpp \
component/edify_test.cpp \
component/imgdiff_test.cpp \
+ component/install_test.cpp \
component/sideload_test.cpp \
component/uncrypt_test.cpp \
component/updater_test.cpp \
@@ -117,6 +118,7 @@ LOCAL_STATIC_LIBRARIES := \
libbsdiff \
libbspatch \
libotafault \
+ librecovery \
libupdater \
libbootloader_message \
libverifier \
@@ -131,7 +133,6 @@ LOCAL_STATIC_LIBRARIES := \
libsparse \
libcrypto_utils \
libcrypto \
- libcutils \
libbz \
libziparchive \
libutils \
diff --git a/tests/component/install_test.cpp b/tests/component/install_test.cpp
new file mode 100644
index 000000000..3b6fbc301
--- /dev/null
+++ b/tests/component/install_test.cpp
@@ -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);
+}