Merge "Explicitly install RemoteProvisioner for keymint"
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index fa556bb..55770f1 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -24,6 +24,7 @@
#include <sched.h>
#include <signal.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -51,7 +52,6 @@
#include "handler/fallback.h"
-using ::android::base::GetBoolProperty;
using ::android::base::ParseBool;
using ::android::base::ParseBoolResult;
using ::android::base::Pipe;
@@ -87,10 +87,25 @@
return syscall(__NR_gettid);
}
+static bool property_parse_bool(const char* name) {
+ const prop_info* pi = __system_property_find(name);
+ if (!pi) return false;
+ bool cookie = false;
+ __system_property_read_callback(
+ pi,
+ [](void* cookie, const char*, const char* value, uint32_t) {
+ *reinterpret_cast<bool*>(cookie) = ParseBool(value) == ParseBoolResult::kTrue;
+ },
+ &cookie);
+ return cookie;
+}
+
static bool is_permissive_mte() {
// Environment variable for testing or local use from shell.
char* permissive_env = getenv("MTE_PERMISSIVE");
- return GetBoolProperty("persist.sys.mte.permissive", false) ||
+ // DO NOT REPLACE this with GetBoolProperty. That uses std::string which allocates, so it is
+ // not async-safe (and this functiong gets used in a signal handler).
+ return property_parse_bool("persist.sys.mte.permissive") ||
(permissive_env && ParseBool(permissive_env) == ParseBoolResult::kTrue);
}
diff --git a/debuggerd/test_permissive_mte/src/com/android/tests/debuggerd/PermissiveMteTest.java b/debuggerd/test_permissive_mte/src/com/android/tests/debuggerd/PermissiveMteTest.java
index 5ff2b5b..0203adc 100644
--- a/debuggerd/test_permissive_mte/src/com/android/tests/debuggerd/PermissiveMteTest.java
+++ b/debuggerd/test_permissive_mte/src/com/android/tests/debuggerd/PermissiveMteTest.java
@@ -97,4 +97,33 @@
}
assertThat(numberTombstones).isEqualTo(1);
}
+ @Test
+ public void testCrashProperty() throws Exception {
+ String prevValue = getDevice().getProperty("persist.sys.mte.permissive");
+ if (prevValue == null) {
+ prevValue = "";
+ }
+ assertThat(getDevice().setProperty("persist.sys.mte.permissive", "1")).isTrue();
+ CommandResult result =
+ getDevice().executeShellV2Command("/data/local/tmp/mte_crash testCrash " + mUUID);
+ assertThat(result.getExitCode()).isEqualTo(0);
+ int numberTombstones = 0;
+ String[] tombstones = getDevice().getChildren("/data/tombstones");
+ for (String tombstone : tombstones) {
+ if (!tombstone.endsWith(".pb")) {
+ continue;
+ }
+ String tombstonePath = "/data/tombstones/" + tombstone;
+ Tombstone tombstoneProto = parseTombstone(tombstonePath);
+ if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains(mUUID))) {
+ continue;
+ }
+ if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains("testCrash"))) {
+ continue;
+ }
+ numberTombstones++;
+ }
+ assertThat(numberTombstones).isEqualTo(1);
+ assertThat(getDevice().setProperty("persist.sys.mte.permissive", prevValue)).isTrue();
+ }
}
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 43961da..76ef9e4 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -309,6 +309,12 @@
if (ReadFileToString("/sys/class/block/" + arg + "/queue/zoned", &zoned) &&
android::base::StartsWith(zoned, "host-managed")) {
entry->zoned_device = "/dev/block/" + arg;
+
+ // atgc in f2fs does not support a zoned device
+ auto options = Split(entry->fs_options, ",");
+ options.erase(std::remove(options.begin(), options.end(), "atgc"), options.end());
+ entry->fs_options = android::base::Join(options, ",");
+ LINFO << "Removed ATGC in fs_options as " << entry->fs_options;
} else {
LWARNING << "Warning: cannot find the zoned device: " << arg;
}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 57762e6..1d5a04b 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -68,10 +68,7 @@
namespace {
bool fs_mgr_access(const std::string& path) {
- auto save_errno = errno;
- auto ret = access(path.c_str(), F_OK) == 0;
- errno = save_errno;
- return ret;
+ return access(path.c_str(), F_OK) == 0;
}
// determine if a filesystem is available
@@ -105,8 +102,8 @@
return false;
}
-bool fs_mgr_overlayfs_teardown(const char*, bool*) {
- return false;
+OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char*, bool*) {
+ return OverlayfsTeardownResult::Ok;
}
bool fs_mgr_overlayfs_is_setup() {
@@ -147,10 +144,7 @@
// is not well-defined. In this case, just return false as being in recovery
// implies not running a DSU system.
if (fs_mgr_in_recovery()) return false;
- auto saved_errno = errno;
- auto ret = android::gsi::IsGsiRunning();
- errno = saved_errno;
- return ret;
+ return android::gsi::IsGsiRunning();
}
// list of acceptable overlayfs backing storage
@@ -193,9 +187,8 @@
// If we have access issues to find out space remaining, return true
// to prevent us trying to override with overlayfs.
struct statvfs vst;
- auto save_errno = errno;
if (statvfs(mount_point.c_str(), &vst)) {
- errno = save_errno;
+ PLOG(ERROR) << "statvfs " << mount_point;
return true;
}
@@ -256,26 +249,21 @@
}
// check if ext4 de-dupe
- auto save_errno = errno;
auto has_shared_blocks = fs_mgr_has_shared_blocks(entry->mount_point, entry->blk_device);
if (!has_shared_blocks && (entry->mount_point == "/system")) {
has_shared_blocks = fs_mgr_has_shared_blocks("/", entry->blk_device);
}
- errno = save_errno;
return has_shared_blocks;
}
bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
- auto save_errno = errno;
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
if (!dir) {
if (errno == ENOENT) {
- errno = save_errno;
return true;
}
PERROR << "opendir " << path << " depth=" << level;
if ((errno == EPERM) && (level != 0)) {
- errno = save_errno;
return true;
}
return false;
@@ -287,9 +275,7 @@
auto file = path + "/" + entry->d_name;
if (entry->d_type == DT_UNKNOWN) {
struct stat st;
- save_errno = errno;
if (!lstat(file.c_str(), &st) && (st.st_mode & S_IFDIR)) entry->d_type = DT_DIR;
- errno = save_errno;
}
if (entry->d_type == DT_DIR) {
ret &= fs_mgr_rm_all(file, change, level + 1);
@@ -363,10 +349,7 @@
bool fs_mgr_rw_access(const std::string& path) {
if (path.empty()) return false;
- auto save_errno = errno;
- auto ret = access(path.c_str(), R_OK | W_OK) == 0;
- errno = save_errno;
- return ret;
+ return access(path.c_str(), R_OK | W_OK) == 0;
}
constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
@@ -481,30 +464,33 @@
return false;
}
-void fs_mgr_overlayfs_umount_scratch() {
- // Lazy umount will allow us to move on and possibly later
- // establish a new fresh mount without requiring a reboot should
- // the developer wish to restart. Old references should melt
- // away or have no data. Main goal is to shut the door on the
- // current overrides with an expectation of a subsequent reboot,
- // thus any errors here are ignored.
- umount2(kScratchMountPoint.c_str(), MNT_DETACH);
- LINFO << "umount(" << kScratchMountPoint << ")";
- rmdir(kScratchMountPoint.c_str());
+// Returns true if immediate unmount succeeded and the scratch mount point was
+// removed.
+bool fs_mgr_overlayfs_umount_scratch() {
+ if (umount(kScratchMountPoint.c_str()) != 0) {
+ return false;
+ }
+ if (rmdir(kScratchMountPoint.c_str()) != 0 && errno != ENOENT) {
+ PLOG(ERROR) << "rmdir " << kScratchMountPoint;
+ }
+ return true;
}
-bool fs_mgr_overlayfs_teardown_scratch(const std::string& overlay, bool* change) {
+OverlayfsTeardownResult fs_mgr_overlayfs_teardown_scratch(const std::string& overlay,
+ bool* change) {
// umount and delete kScratchMountPoint storage if we have logical partitions
- if (overlay != kScratchMountPoint) return true;
+ if (overlay != kScratchMountPoint) {
+ return OverlayfsTeardownResult::Ok;
+ }
// Validation check.
if (fs_mgr_is_dsu_running()) {
LERROR << "Destroying DSU scratch is not allowed.";
- return false;
+ return OverlayfsTeardownResult::Error;
}
- auto save_errno = errno;
- if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) {
+ bool was_mounted = fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false);
+ if (was_mounted) {
fs_mgr_overlayfs_umount_scratch();
}
@@ -512,42 +498,55 @@
auto images = IImageManager::Open("remount", 10s);
if (images && images->BackingImageExists(partition_name)) {
-#if defined __ANDROID_RECOVERY__
if (!images->DisableImage(partition_name)) {
- return false;
+ return OverlayfsTeardownResult::Error;
}
-#else
- if (!images->UnmapImageIfExists(partition_name) ||
- !images->DeleteBackingImage(partition_name)) {
- return false;
+ if (was_mounted) {
+ // If overlayfs was mounted, don't bother trying to unmap since
+ // it'll fail and create error spam.
+ return OverlayfsTeardownResult::Busy;
}
-#endif
+ if (!images->UnmapImageIfExists(partition_name)) {
+ return OverlayfsTeardownResult::Busy;
+ }
+ if (!images->DeleteBackingImage(partition_name)) {
+ return OverlayfsTeardownResult::Busy;
+ }
+
+ // No need to check super partition, if we knew we had a scratch device
+ // in /data.
+ return OverlayfsTeardownResult::Ok;
}
auto slot_number = fs_mgr_overlayfs_slot_number();
auto super_device = fs_mgr_overlayfs_super_device(slot_number);
- if (!fs_mgr_rw_access(super_device)) return true;
+ if (!fs_mgr_rw_access(super_device)) {
+ return OverlayfsTeardownResult::Ok;
+ }
auto builder = MetadataBuilder::New(super_device, slot_number);
if (!builder) {
- errno = save_errno;
- return true;
+ return OverlayfsTeardownResult::Ok;
}
if (builder->FindPartition(partition_name) == nullptr) {
- errno = save_errno;
- return true;
+ return OverlayfsTeardownResult::Ok;
}
builder->RemovePartition(partition_name);
auto metadata = builder->Export();
if (metadata && UpdatePartitionTable(super_device, *metadata.get(), slot_number)) {
if (change) *change = true;
- if (!DestroyLogicalPartition(partition_name)) return false;
+ if (!DestroyLogicalPartition(partition_name)) {
+ return OverlayfsTeardownResult::Error;
+ }
} else {
LERROR << "delete partition " << overlay;
- return false;
+ return OverlayfsTeardownResult::Error;
}
- errno = save_errno;
- return true;
+
+ if (was_mounted) {
+ return OverlayfsTeardownResult::Busy;
+ }
+ return OverlayfsTeardownResult::Ok;
}
bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
@@ -565,27 +564,20 @@
const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir.substr(1) + ".teardown"
: top + "/." + partition_name + ".teardown";
auto ret = fs_mgr_rm_all(newpath);
- auto save_errno = errno;
if (!rename(oldpath.c_str(), newpath.c_str())) {
if (change) *change = true;
} else if (errno != ENOENT) {
ret = false;
PERROR << "mv " << oldpath << " " << newpath;
- } else {
- errno = save_errno;
}
ret &= fs_mgr_rm_all(newpath, change);
- save_errno = errno;
if (!rmdir(newpath.c_str())) {
if (change) *change = true;
} else if (errno != ENOENT) {
ret = false;
PERROR << "rmdir " << newpath;
- } else {
- errno = save_errno;
}
if (!cleanup_all) {
- save_errno = errno;
if (!rmdir(top.c_str())) {
if (change) *change = true;
cleanup_all = true;
@@ -604,10 +596,8 @@
}
}
}
- errno = save_errno;
} else if (errno == ENOENT) {
cleanup_all = true;
- errno = save_errno;
} else {
ret = false;
PERROR << "rmdir " << top;
@@ -718,7 +708,6 @@
if (options.empty()) return false;
auto retval = true;
- auto save_errno = errno;
struct move_entry {
std::string mount_point;
@@ -761,7 +750,6 @@
}
if (!target) {
retval = false;
- save_errno = errno;
PERROR << "temporary directory for MS_BIND";
continue;
}
@@ -774,7 +762,6 @@
}
if (!fs_mgr_overlayfs_move_mount(new_entry.mount_point, new_entry.dir)) {
retval = false;
- save_errno = errno;
if (new_entry.shared_flag) {
fs_mgr_overlayfs_set_shared_mount(new_entry.mount_point, true);
}
@@ -798,7 +785,6 @@
options.c_str());
if (ret) {
retval = false;
- save_errno = errno;
PERROR << report << ret;
} else {
LINFO << report << ret;
@@ -812,11 +798,9 @@
if (!fs_mgr_overlayfs_move_mount(entry.dir, entry.mount_point)) {
retval = false;
- save_errno = errno;
} else if (entry.shared_flag &&
!fs_mgr_overlayfs_set_shared_mount(entry.mount_point, true)) {
retval = false;
- save_errno = errno;
}
rmdir(entry.dir.c_str());
}
@@ -827,7 +811,6 @@
fs_mgr_overlayfs_set_shared_mount(mount_point, true);
}
- errno = save_errno;
return retval;
}
@@ -869,17 +852,6 @@
entry.flags = MS_NOATIME | MS_RDONLY;
auto mounted = true;
if (!readonly) {
- if (entry.fs_type == "ext4") {
- // check if ext4 de-dupe
- entry.flags |= MS_RDONLY;
- auto save_errno = errno;
- mounted = fs_mgr_do_mount_one(entry) == 0;
- if (mounted) {
- mounted = !fs_mgr_has_shared_blocks(entry.mount_point, entry.blk_device);
- fs_mgr_overlayfs_umount_scratch();
- }
- errno = save_errno;
- }
entry.flags &= ~MS_RDONLY;
entry.flags |= MS_SYNCHRONOUS;
entry.fs_options = "nodiscard";
@@ -1246,7 +1218,10 @@
return true;
}
// declare it useless, no overrides and no free space
- fs_mgr_overlayfs_umount_scratch();
+ if (!fs_mgr_overlayfs_umount_scratch()) {
+ LOG(ERROR) << "Unable to unmount scratch partition";
+ return false;
+ }
}
}
@@ -1548,12 +1523,38 @@
return true;
}
-// Returns false if teardown not permitted, errno set to last error.
-// If something is altered, set *change.
-bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
- if (change) *change = false;
- auto ret = true;
+OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* want_reboot) {
+ bool should_destroy_scratch = false;
+ auto rv = OverlayfsTeardownResult::Ok;
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
+ auto ok = fs_mgr_overlayfs_teardown_one(
+ overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "",
+ want_reboot,
+ overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr);
+ if (!ok) {
+ rv = OverlayfsTeardownResult::Error;
+ }
+ }
+ // Do not attempt to destroy DSU scratch if within a DSU system,
+ // because DSU scratch partition is managed by gsid.
+ if (should_destroy_scratch && !fs_mgr_is_dsu_running()) {
+ auto rv = fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, want_reboot);
+ if (rv != OverlayfsTeardownResult::Ok) {
+ return rv;
+ }
+ }
+ // And now that we did what we could, lets inform
+ // caller that there may still be more to do.
+ if (!fs_mgr_boot_completed()) {
+ LOG(ERROR) << "Cannot teardown overlayfs before persistent properties are ready";
+ return OverlayfsTeardownResult::Error;
+ }
+ return rv;
+}
+
+// Returns false if teardown not permitted. If something is altered, set *want_reboot.
+OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool* want_reboot) {
// If scratch exists, but is not mounted, lets gain access to clean
// specific override entries.
auto mount_scratch = false;
@@ -1564,34 +1565,15 @@
fs_mgr_overlayfs_scratch_mount_type());
}
}
- bool should_destroy_scratch = false;
- for (const auto& overlay_mount_point : OverlayMountPoints()) {
- ret &= fs_mgr_overlayfs_teardown_one(
- overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change,
- overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr);
- }
- // Do not attempt to destroy DSU scratch if within a DSU system,
- // because DSU scratch partition is managed by gsid.
- if (should_destroy_scratch && !fs_mgr_is_dsu_running()) {
- ret &= fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, change);
- }
- if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
- // After obligatory teardown to make sure everything is clean, but if
- // we didn't want overlayfs in the first place, we do not want to
- // waste time on a reboot (or reboot request message).
- if (change) *change = false;
- }
- // And now that we did what we could, lets inform
- // caller that there may still be more to do.
- if (!fs_mgr_boot_completed()) {
- errno = EBUSY;
- PERROR << "teardown";
- ret = false;
- }
+
+ auto rv = TeardownMountsAndScratch(mount_point, want_reboot);
+
if (mount_scratch) {
- fs_mgr_overlayfs_umount_scratch();
+ if (!fs_mgr_overlayfs_umount_scratch()) {
+ return OverlayfsTeardownResult::Busy;
+ }
}
- return ret;
+ return rv;
}
bool fs_mgr_overlayfs_is_setup() {
@@ -1689,6 +1671,7 @@
}
}
+ // Note if we just disabled scratch, this mount will fail.
if (auto info = EnsureScratchMapped(); info.has_value()) {
// Map scratch device, mount kScratchMountPoint and teardown kScratchMountPoint.
fs_mgr_overlayfs_umount_scratch();
@@ -1722,11 +1705,9 @@
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only) {
Fstab fstab;
- auto save_errno = errno;
if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
return false;
}
- errno = save_errno;
const auto lowerdir = kLowerdirOption + mount_point;
for (const auto& entry : fstab) {
if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue;
diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h
index 590f66b..4d9b13f 100644
--- a/fs_mgr/include/fs_mgr_overlayfs.h
+++ b/fs_mgr/include/fs_mgr_overlayfs.h
@@ -28,7 +28,6 @@
bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab);
-bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);
bool fs_mgr_overlayfs_is_setup();
bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev);
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
@@ -42,6 +41,14 @@
bool fs_mgr_overlayfs_setup(const char* mount_point = nullptr, bool* want_reboot = nullptr,
bool just_disabled_verity = true);
+enum class OverlayfsTeardownResult {
+ Ok,
+ Busy, // Indicates that overlays are still in use.
+ Error
+};
+OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point = nullptr,
+ bool* want_reboot = nullptr);
+
enum class OverlayfsValidResult {
kNotSupported = 0,
kOk,
diff --git a/fs_mgr/libfiemap/binder.cpp b/fs_mgr/libfiemap/binder.cpp
index 003e6ed..41e534a 100644
--- a/fs_mgr/libfiemap/binder.cpp
+++ b/fs_mgr/libfiemap/binder.cpp
@@ -195,9 +195,14 @@
return true;
}
-bool ImageManagerBinder::DisableImage(const std::string&) {
- LOG(ERROR) << __PRETTY_FUNCTION__ << " is not available over binder";
- return false;
+bool ImageManagerBinder::DisableImage(const std::string& name) {
+ auto status = manager_->disableImage(name);
+ if (!status.isOk()) {
+ LOG(ERROR) << __PRETTY_FUNCTION__
+ << " binder returned: " << status.exceptionMessage().string();
+ return false;
+ }
+ return true;
}
bool ImageManagerBinder::RemoveDisabledImages() {
diff --git a/fs_mgr/libfiemap/include/libfiemap/image_manager.h b/fs_mgr/libfiemap/include/libfiemap/image_manager.h
index 00dd661..0619c96 100644
--- a/fs_mgr/libfiemap/include/libfiemap/image_manager.h
+++ b/fs_mgr/libfiemap/include/libfiemap/image_manager.h
@@ -112,9 +112,6 @@
// Mark an image as disabled. This is useful for marking an image as
// will-be-deleted in recovery, since recovery cannot mount /data.
- //
- // This is not available in binder, since it is intended for recovery.
- // When binder is available, images can simply be removed.
virtual bool DisableImage(const std::string& name) = 0;
// Remove all images that been marked as disabled.
diff --git a/fs_mgr/libsnapshot/vts_ota_config_test.cpp b/fs_mgr/libsnapshot/vts_ota_config_test.cpp
old mode 100644
new mode 100755
index 02bcc34..d387eb3
--- a/fs_mgr/libsnapshot/vts_ota_config_test.cpp
+++ b/fs_mgr/libsnapshot/vts_ota_config_test.cpp
@@ -22,6 +22,9 @@
}
TEST(VAB, Enabled) {
+ if (!android::base::GetBoolProperty("ro.build.ab_update", false) && (GetVsrLevel() < __ANDROID_API_T__)) {
+ GTEST_SKIP();
+ }
ASSERT_TRUE(android::base::GetBoolProperty("ro.virtual_ab.enabled", false));
if (GetVsrLevel() < __ANDROID_API_T__) {
GTEST_SKIP();
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
index fdc0d8e..b9bae25 100644
--- a/fs_mgr/tests/Android.bp
+++ b/fs_mgr/tests/Android.bp
@@ -53,8 +53,9 @@
}
sh_binary_host {
- name: "adb-remount-test.sh",
+ name: "adb-remount-test",
src: "adb-remount-test.sh",
+ filename_from_src: true,
target: {
darwin: {
enabled: false,
@@ -68,7 +69,7 @@
sh_test {
name: "adb-remount-sh",
src: "adb-remount-test.sh",
- filename: "adb-remount-test.sh",
+ filename_from_src: true,
test_suites: ["general-tests"],
test_config: "adb-remount-sh.xml",
}
diff --git a/gatekeeperd/Android.bp b/gatekeeperd/Android.bp
index 0aedc58..838f734 100644
--- a/gatekeeperd/Android.bp
+++ b/gatekeeperd/Android.bp
@@ -43,6 +43,8 @@
"libutils",
"libcrypto",
"libhidlbase",
+ "lib_android_keymaster_keymint_utils",
+ "android.hardware.gatekeeper-V1-ndk",
"android.hardware.gatekeeper@1.0",
"libgatekeeper_aidl",
"android.security.authorization-ndk",
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index 8792c83..76fcd55 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <memory>
+#include <KeyMintUtils.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android/binder_ibinder.h>
@@ -38,6 +39,7 @@
#include <log/log.h>
#include <utils/String16.h>
+#include <aidl/android/hardware/gatekeeper/IGatekeeper.h>
#include <aidl/android/hardware/security/keymint/HardwareAuthToken.h>
#include <aidl/android/security/authorization/IKeystoreAuthorization.h>
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@@ -49,27 +51,35 @@
using android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
using android::hardware::gatekeeper::V1_0::IGatekeeper;
+using AidlGatekeeperEnrollResp = aidl::android::hardware::gatekeeper::GatekeeperEnrollResponse;
+using AidlGatekeeperVerifyResp = aidl::android::hardware::gatekeeper::GatekeeperVerifyResponse;
+using AidlIGatekeeper = aidl::android::hardware::gatekeeper::IGatekeeper;
+
using ::android::binder::Status;
using ::android::service::gatekeeper::BnGateKeeperService;
using GKResponse = ::android::service::gatekeeper::GateKeeperResponse;
using GKResponseCode = ::android::service::gatekeeper::ResponseCode;
using ::aidl::android::hardware::security::keymint::HardwareAuthenticatorType;
using ::aidl::android::hardware::security::keymint::HardwareAuthToken;
+using ::aidl::android::hardware::security::keymint::km_utils::authToken2AidlVec;
using ::aidl::android::security::authorization::IKeystoreAuthorization;
namespace android {
static const String16 KEYGUARD_PERMISSION("android.permission.ACCESS_KEYGUARD_SECURE_STORAGE");
static const String16 DUMP_PERMISSION("android.permission.DUMP");
+constexpr const char gatekeeperServiceName[] = "android.hardware.gatekeeper.IGatekeeper/default";
class GateKeeperProxy : public BnGateKeeperService {
public:
GateKeeperProxy() {
clear_state_if_needed_done = false;
hw_device = IGatekeeper::getService();
+ ::ndk::SpAIBinder ks2Binder(AServiceManager_getService(gatekeeperServiceName));
+ aidl_hw_device = AidlIGatekeeper::fromBinder(ks2Binder);
is_running_gsi = android::base::GetBoolProperty(android::gsi::kGsiBootedProp, false);
- if (!hw_device) {
+ if (!aidl_hw_device && !hw_device) {
LOG(ERROR) << "Could not find Gatekeeper device, which makes me very sad.";
}
}
@@ -95,7 +105,9 @@
if (mark_cold_boot() && !is_running_gsi) {
ALOGI("cold boot: clearing state");
- if (hw_device) {
+ if (aidl_hw_device) {
+ aidl_hw_device->deleteAllUsers();
+ } else if (hw_device) {
hw_device->deleteAllUsers([](const GatekeeperResponse&) {});
}
}
@@ -150,7 +162,7 @@
uint32_t adjust_userId(uint32_t userId) {
static constexpr uint32_t kGsiOffset = 1000000;
CHECK(userId < kGsiOffset);
- CHECK(hw_device != nullptr);
+ CHECK((aidl_hw_device != nullptr) || (hw_device != nullptr));
if (is_running_gsi) {
return userId + kGsiOffset;
}
@@ -176,7 +188,7 @@
// need a desired password to enroll
if (desiredPassword.size() == 0) return GK_ERROR;
- if (!hw_device) {
+ if (!aidl_hw_device && !hw_device) {
LOG(ERROR) << "has no HAL to talk to";
return GK_ERROR;
}
@@ -185,9 +197,13 @@
android::hardware::hidl_vec<uint8_t> curPwd;
if (currentPasswordHandle && currentPassword) {
- if (currentPasswordHandle->size() != sizeof(gatekeeper::password_handle_t)) {
- LOG(INFO) << "Password handle has wrong length";
- return GK_ERROR;
+ if (hw_device) {
+ // Hidl Implementations expects passwordHandle to be in
+ // gatekeeper::password_handle_t format.
+ if (currentPasswordHandle->size() != sizeof(gatekeeper::password_handle_t)) {
+ LOG(INFO) << "Password handle has wrong length";
+ return GK_ERROR;
+ }
}
curPwdHandle.setToExternal(const_cast<uint8_t*>(currentPasswordHandle->data()),
currentPasswordHandle->size());
@@ -199,7 +215,27 @@
newPwd.setToExternal(const_cast<uint8_t*>(desiredPassword.data()), desiredPassword.size());
uint32_t hw_userId = adjust_userId(userId);
- Return<void> hwRes = hw_device->enroll(
+ uint64_t secureUserId = 0;
+ if (aidl_hw_device) {
+ // AIDL gatekeeper service
+ AidlGatekeeperEnrollResp rsp;
+ auto result = aidl_hw_device->enroll(hw_userId, curPwdHandle, curPwd, newPwd, &rsp);
+ if (!result.isOk()) {
+ LOG(ERROR) << "enroll transaction failed";
+ return GK_ERROR;
+ }
+ if (rsp.statusCode >= AidlIGatekeeper::STATUS_OK) {
+ *gkResponse = GKResponse::ok({rsp.data.begin(), rsp.data.end()});
+ secureUserId = static_cast<uint64_t>(rsp.secureUserId);
+ } else if (rsp.statusCode == AidlIGatekeeper::ERROR_RETRY_TIMEOUT &&
+ rsp.timeoutMs > 0) {
+ *gkResponse = GKResponse::retry(rsp.timeoutMs);
+ } else {
+ *gkResponse = GKResponse::error();
+ }
+ } else if (hw_device) {
+ // HIDL gatekeeper service
+ Return<void> hwRes = hw_device->enroll(
hw_userId, curPwdHandle, curPwd, newPwd,
[&gkResponse](const GatekeeperResponse& rsp) {
if (rsp.code >= GatekeeperStatusCode::STATUS_OK) {
@@ -211,22 +247,26 @@
*gkResponse = GKResponse::error();
}
});
- if (!hwRes.isOk()) {
- LOG(ERROR) << "enroll transaction failed";
- return GK_ERROR;
+ if (!hwRes.isOk()) {
+ LOG(ERROR) << "enroll transaction failed";
+ return GK_ERROR;
+ }
+ if (gkResponse->response_code() == GKResponseCode::OK) {
+ if (gkResponse->payload().size() != sizeof(gatekeeper::password_handle_t)) {
+ LOG(ERROR) << "HAL returned password handle of invalid length "
+ << gkResponse->payload().size();
+ return GK_ERROR;
+ }
+
+ const gatekeeper::password_handle_t* handle =
+ reinterpret_cast<const gatekeeper::password_handle_t*>(
+ gkResponse->payload().data());
+ secureUserId = handle->user_id;
+ }
}
if (gkResponse->response_code() == GKResponseCode::OK && !gkResponse->should_reenroll()) {
- if (gkResponse->payload().size() != sizeof(gatekeeper::password_handle_t)) {
- LOG(ERROR) << "HAL returned password handle of invalid length "
- << gkResponse->payload().size();
- return GK_ERROR;
- }
-
- const gatekeeper::password_handle_t* handle =
- reinterpret_cast<const gatekeeper::password_handle_t*>(
- gkResponse->payload().data());
- store_sid(userId, handle->user_id);
+ store_sid(userId, secureUserId);
GKResponse verifyResponse;
// immediately verify this password so we don't ask the user to enter it again
@@ -260,15 +300,18 @@
// can't verify if we're missing either param
if (enrolledPasswordHandle.size() == 0 || providedPassword.size() == 0) return GK_ERROR;
- if (!hw_device) return GK_ERROR;
-
- if (enrolledPasswordHandle.size() != sizeof(gatekeeper::password_handle_t)) {
- LOG(INFO) << "Password handle has wrong length";
+ if (!aidl_hw_device && !hw_device) {
+ LOG(ERROR) << "has no HAL to talk to";
return GK_ERROR;
}
- const gatekeeper::password_handle_t* handle =
- reinterpret_cast<const gatekeeper::password_handle_t*>(
- enrolledPasswordHandle.data());
+
+ if (hw_device) {
+ // Hidl Implementations expects passwordHandle to be in gatekeeper::password_handle_t
+ if (enrolledPasswordHandle.size() != sizeof(gatekeeper::password_handle_t)) {
+ LOG(INFO) << "Password handle has wrong length";
+ return GK_ERROR;
+ }
+ }
uint32_t hw_userId = adjust_userId(userId);
android::hardware::hidl_vec<uint8_t> curPwdHandle;
@@ -278,13 +321,36 @@
enteredPwd.setToExternal(const_cast<uint8_t*>(providedPassword.data()),
providedPassword.size());
- Return<void> hwRes = hw_device->verify(
+ uint64_t secureUserId = 0;
+ if (aidl_hw_device) {
+ // AIDL gatekeeper service
+ AidlGatekeeperVerifyResp rsp;
+ auto result =
+ aidl_hw_device->verify(hw_userId, challenge, curPwdHandle, enteredPwd, &rsp);
+ if (!result.isOk()) {
+ LOG(ERROR) << "verify transaction failed";
+ return GK_ERROR;
+ }
+ if (rsp.statusCode >= AidlIGatekeeper::STATUS_OK) {
+ secureUserId = rsp.hardwareAuthToken.userId;
+ // Serialize HardwareAuthToken to a vector as hw_auth_token_t.
+ *gkResponse = GKResponse::ok(authToken2AidlVec(rsp.hardwareAuthToken),
+ rsp.statusCode ==
+ AidlIGatekeeper::STATUS_REENROLL /* reenroll */);
+ } else if (rsp.statusCode == AidlIGatekeeper::ERROR_RETRY_TIMEOUT) {
+ *gkResponse = GKResponse::retry(rsp.timeoutMs);
+ } else {
+ *gkResponse = GKResponse::error();
+ }
+ } else if (hw_device) {
+ // HIDL gatekeeper service
+ Return<void> hwRes = hw_device->verify(
hw_userId, challenge, curPwdHandle, enteredPwd,
[&gkResponse](const GatekeeperResponse& rsp) {
if (rsp.code >= GatekeeperStatusCode::STATUS_OK) {
*gkResponse = GKResponse::ok(
- {rsp.data.begin(), rsp.data.end()},
- rsp.code == GatekeeperStatusCode::STATUS_REENROLL /* reenroll */);
+ {rsp.data.begin(), rsp.data.end()},
+ rsp.code == GatekeeperStatusCode::STATUS_REENROLL /* reenroll */);
} else if (rsp.code == GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) {
*gkResponse = GKResponse::retry(rsp.timeout);
} else {
@@ -292,9 +358,14 @@
}
});
- if (!hwRes.isOk()) {
- LOG(ERROR) << "verify transaction failed";
- return GK_ERROR;
+ if (!hwRes.isOk()) {
+ LOG(ERROR) << "verify transaction failed";
+ return GK_ERROR;
+ }
+ const gatekeeper::password_handle_t* handle =
+ reinterpret_cast<const gatekeeper::password_handle_t*>(
+ enrolledPasswordHandle.data());
+ secureUserId = handle->user_id;
}
if (gkResponse->response_code() == GKResponseCode::OK) {
@@ -333,7 +404,7 @@
}
}
- maybe_store_sid(userId, handle->user_id);
+ maybe_store_sid(userId, secureUserId);
}
return Status::ok();
@@ -354,8 +425,10 @@
}
clear_sid(userId);
- if (hw_device) {
- uint32_t hw_userId = adjust_userId(userId);
+ uint32_t hw_userId = adjust_userId(userId);
+ if (aidl_hw_device) {
+ aidl_hw_device->deleteUser(hw_userId);
+ } else if (hw_device) {
hw_device->deleteUser(hw_userId, [](const GatekeeperResponse&) {});
}
return Status::ok();
@@ -382,7 +455,7 @@
return PERMISSION_DENIED;
}
- if (hw_device == NULL) {
+ if (aidl_hw_device == nullptr && hw_device == nullptr) {
const char* result = "Device not available";
write(fd, result, strlen(result) + 1);
} else {
@@ -394,6 +467,9 @@
}
private:
+ // AIDL gatekeeper service.
+ std::shared_ptr<AidlIGatekeeper> aidl_hw_device;
+ // HIDL gatekeeper service.
sp<IGatekeeper> hw_device;
bool clear_state_if_needed_done;
@@ -414,8 +490,8 @@
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
android::sp<android::GateKeeperProxy> proxy = new android::GateKeeperProxy();
- android::status_t ret = sm->addService(
- android::String16("android.service.gatekeeper.IGateKeeperService"), proxy);
+ android::status_t ret =
+ sm->addService(android::String16("android.service.gatekeeper.IGateKeeperService"), proxy);
if (ret != android::OK) {
ALOGE("Couldn't register binder service!");
return -1;
diff --git a/healthd/healthd_draw.cpp b/healthd/healthd_draw.cpp
index 3e73fcd..7c79319 100644
--- a/healthd/healthd_draw.cpp
+++ b/healthd/healthd_draw.cpp
@@ -99,7 +99,7 @@
gr_fb_blank(blank, drm);
}
-/* support screen rotation for foldable phone */
+// support screen rotation for foldable phone
void HealthdDraw::rotate_screen(int drm) {
if (!graphics_available) return;
if (drm == 0)
@@ -108,6 +108,11 @@
gr_rotate(GRRotation::NONE /* Portrait mode */);
}
+// detect dual display
+bool HealthdDraw::has_multiple_connectors() {
+ return graphics_available && gr_has_multiple_connectors();
+}
+
void HealthdDraw::clear_screen(void) {
if (!graphics_available) return;
gr_color(0, 0, 0, 255);
diff --git a/healthd/healthd_draw.h b/healthd/healthd_draw.h
index 3d4abbd..016db8e 100644
--- a/healthd/healthd_draw.h
+++ b/healthd/healthd_draw.h
@@ -38,6 +38,9 @@
// Rotate screen.
virtual void rotate_screen(int drm);
+ // Detect dual display
+ virtual bool has_multiple_connectors();
+
static std::unique_ptr<HealthdDraw> Create(animation *anim);
protected:
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index e305a86..1ce174b 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -289,6 +289,18 @@
anim->run = false;
}
+void Charger::BlankSecScreen() {
+ int drm = drm_ == DRM_INNER ? 1 : 0;
+
+ if (!init_screen_) {
+ /* blank the secondary screen */
+ healthd_draw_->blank_screen(false, drm);
+ healthd_draw_->redraw_screen(&batt_anim_, surf_unknown_);
+ healthd_draw_->blank_screen(true, drm);
+ init_screen_ = true;
+ }
+}
+
void Charger::UpdateScreenState(int64_t now) {
int disp_time;
@@ -315,6 +327,9 @@
reset_animation(&batt_anim_);
next_screen_transition_ = -1;
healthd_draw_->blank_screen(true, static_cast<int>(drm_));
+ if (healthd_draw_->has_multiple_connectors()) {
+ BlankSecScreen();
+ }
screen_blanked_ = true;
LOGV("[%" PRId64 "] animation done\n", now);
if (configuration_->ChargerIsOnline()) {
diff --git a/healthd/include_charger/charger/healthd_mode_charger.h b/healthd/include_charger/charger/healthd_mode_charger.h
index 82e4ddf..c463b92 100644
--- a/healthd/include_charger/charger/healthd_mode_charger.h
+++ b/healthd/include_charger/charger/healthd_mode_charger.h
@@ -108,9 +108,11 @@
void InitAnimation();
int RequestEnableSuspend();
int RequestDisableSuspend();
+ void BlankSecScreen();
bool have_battery_state_ = false;
bool screen_blanked_ = false;
+ bool init_screen_ = false;
int64_t next_screen_transition_ = 0;
int64_t next_key_check_ = 0;
int64_t next_pwr_check_ = 0;
diff --git a/init/Android.bp b/init/Android.bp
index 20d622d..6255305 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -276,7 +276,7 @@
"init.rc",
"ueventd.rc",
"e2fsdroid",
- "extra_free_kbytes.sh",
+ "extra_free_kbytes",
"make_f2fs",
"mke2fs",
"sload_f2fs",
@@ -609,6 +609,7 @@
}
sh_binary {
- name: "extra_free_kbytes.sh",
+ name: "extra_free_kbytes",
src: "extra_free_kbytes.sh",
+ filename_from_src: true,
}
diff --git a/libsparse/Android.bp b/libsparse/Android.bp
index 02bfee6..8e83e16 100644
--- a/libsparse/Android.bp
+++ b/libsparse/Android.bp
@@ -80,16 +80,12 @@
}
python_binary_host {
- name: "simg_dump.py",
+ name: "simg_dump",
main: "simg_dump.py",
srcs: ["simg_dump.py"],
version: {
- py2: {
- enabled: false,
- },
py3: {
embedded_launcher: true,
- enabled: true,
},
},
}
diff --git a/set-verity-state/set-verity-state.cpp b/set-verity-state/set-verity-state.cpp
index 3c0df79..2b9c0ca 100644
--- a/set-verity-state/set-verity-state.cpp
+++ b/set-verity-state/set-verity-state.cpp
@@ -47,6 +47,33 @@
const bool kAllowDisableVerity = false;
#endif
+static bool SetupOrTeardownOverlayfs(bool enable) {
+ bool want_reboot = false;
+ if (enable) {
+ if (!fs_mgr_overlayfs_setup(nullptr, &want_reboot)) {
+ LOG(ERROR) << "Overlayfs setup failed.";
+ return want_reboot;
+ }
+ if (want_reboot) {
+ printf("enabling overlayfs\n");
+ }
+ } else {
+ auto rv = fs_mgr_overlayfs_teardown(nullptr, &want_reboot);
+ if (rv == OverlayfsTeardownResult::Error) {
+ LOG(ERROR) << "Overlayfs teardown failed.";
+ return want_reboot;
+ }
+ if (rv == OverlayfsTeardownResult::Busy) {
+ LOG(ERROR) << "Overlayfs is still active until reboot.";
+ return true;
+ }
+ if (want_reboot) {
+ printf("disabling overlayfs\n");
+ }
+ }
+ return want_reboot;
+}
+
/* Helper function to get A/B suffix, if any. If the device isn't
* using A/B the empty string is returned. Otherwise either "_a",
* "_b", ... is returned.
@@ -79,20 +106,6 @@
::exit(1);
}
-bool overlayfs_setup(bool enable) {
- auto want_reboot = false;
- errno = 0;
- if (enable ? fs_mgr_overlayfs_setup(nullptr, &want_reboot)
- : fs_mgr_overlayfs_teardown(nullptr, &want_reboot)) {
- if (want_reboot) {
- LOG(INFO) << (enable ? "Enabled" : "Disabled") << " overlayfs";
- }
- } else {
- LOG(ERROR) << "Failed to " << (enable ? "enable" : "disable") << " overlayfs";
- }
- return want_reboot;
-}
-
struct SetVerityStateResult {
bool success = false;
bool want_reboot = false;
@@ -229,7 +242,7 @@
// Start a threadpool to service waitForService() callbacks as
// fs_mgr_overlayfs_* might call waitForService() to get the image service.
android::ProcessState::self()->startThreadPool();
- want_reboot |= overlayfs_setup(!enable_verity);
+ want_reboot |= SetupOrTeardownOverlayfs(!enable_verity);
}
if (want_reboot) {