Merge "Load default prop from /system/etc/prop.default" into oc-dr1-dev
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index f5d0f02..e533a00 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -125,7 +125,7 @@
static int _adb_connect(const std::string& service, std::string* error) {
D("_adb_connect: %s", service.c_str());
- if (service.empty() || service.size() > MAX_PAYLOAD_V1) {
+ if (service.empty() || service.size() > MAX_PAYLOAD) {
*error = android::base::StringPrintf("bad service name length (%zd)",
service.size());
return -1;
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index ca8729e..38e3116 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -31,7 +31,7 @@
bool SendProtocolString(int fd, const std::string& s) {
unsigned int length = s.size();
- if (length > MAX_PAYLOAD_V1 - 4) {
+ if (length > MAX_PAYLOAD - 4) {
errno = EMSGSIZE;
return false;
}
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 68ae4af..c9f1ee9 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -599,6 +599,13 @@
std::string service_string = ShellServiceString(use_shell_protocol,
type_arg, command);
+ // Old devices can't handle a service string that's longer than MAX_PAYLOAD_V1.
+ // Use |use_shell_protocol| to determine whether to allow a command longer than that.
+ if (service_string.size() > MAX_PAYLOAD_V1 && !use_shell_protocol) {
+ fprintf(stderr, "error: shell command too long\n");
+ return 1;
+ }
+
// Make local stdin raw if the device allocates a PTY, which happens if:
// 1. We are explicitly asking for a PTY shell, or
// 2. We don't specify shell type and are starting an interactive session.
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 14ad1ff..e0143c6 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -686,7 +686,7 @@
}
len = unhex(p->data, 4);
- if ((len < 1) || (len > MAX_PAYLOAD_V1)) {
+ if ((len < 1) || (len > MAX_PAYLOAD)) {
D("SS(%d): bad size (%d)", s->id, len);
goto fail;
}
diff --git a/adb/test_device.py b/adb/test_device.py
index 737d0c2..9e1a2ec 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -342,6 +342,13 @@
out = self.device.shell(['echo', 'foo'])[0]
self.assertEqual(out, 'foo' + self.device.linesep)
+ def test_shell_command_length(self):
+ # Devices that have shell_v2 should be able to handle long commands.
+ if self.device.has_shell_protocol():
+ rc, out, err = self.device.shell_nocheck(['echo', 'x' * 16384])
+ self.assertEqual(rc, 0)
+ self.assertTrue(out == ('x' * 16384 + '\n'))
+
def test_shell_nocheck_failure(self):
rc, out, _ = self.device.shell_nocheck(['false'])
self.assertNotEqual(rc, 0)
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 308ee8d..2bbbefd 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -603,15 +603,15 @@
static void transport_unref(atransport* t) {
CHECK(t != nullptr);
- std::lock_guard<std::mutex> lock(transport_lock);
- CHECK_GT(t->ref_count, 0u);
- t->ref_count--;
- if (t->ref_count == 0) {
+ size_t old_refcount = t->ref_count--;
+ CHECK_GT(old_refcount, 0u);
+
+ if (old_refcount == 1u) {
D("transport: %s unref (kicking and closing)", t->serial);
t->close(t);
remove_transport(t);
} else {
- D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
+ D("transport: %s unref (count=%zu)", t->serial, old_refcount - 1);
}
}
diff --git a/adb/transport.h b/adb/transport.h
index 57fc988..4a89ed9 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -61,7 +61,7 @@
// class in one go is a very large change. Given how bad our testing is,
// it's better to do this piece by piece.
- atransport(ConnectionState state = kCsOffline) : connection_state_(state) {
+ atransport(ConnectionState state = kCsOffline) : ref_count(0), connection_state_(state) {
transport_fde = {};
protocol_version = A_VERSION;
max_payload = MAX_PAYLOAD;
@@ -88,7 +88,7 @@
int fd = -1;
int transport_socket = -1;
fdevent transport_fde;
- size_t ref_count = 0;
+ std::atomic<size_t> ref_count;
uint32_t sync_token = 0;
bool online = false;
TransportType type = kTransportAny;
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 558bc72..5db0e5f 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -271,7 +271,10 @@
}
// Die if we take too long.
- alarm(2);
+ //
+ // Note: processes with many threads and minidebug-info can take a bit to
+ // unwind, do not make this too small. b/62828735
+ alarm(5);
std::string attach_error;
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 9008b95..2015157 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -305,7 +305,7 @@
std::string result;
ConsumeFd(std::move(output_fd), &result);
- ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
+ ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)");
}
TEST_F(CrasherTest, signal) {
@@ -452,7 +452,7 @@
FinishIntercept(&intercept_result);
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
ConsumeFd(std::move(output_fd), &result);
- ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
+ ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)");
}
TEST_F(CrasherTest, PR_SET_DUMPABLE_0_crash) {
@@ -472,7 +472,7 @@
std::string result;
ConsumeFd(std::move(output_fd), &result);
- ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
+ ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)");
}
TEST_F(CrasherTest, capabilities) {
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index 7f450e6..22fde5e 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -22,22 +22,16 @@
#include <signal.h>
#include <string.h>
#include <sys/ptrace.h>
-#include <sys/uio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <backtrace/Backtrace.h>
#include <log/log.h>
-using android::base::unique_fd;
-
// Whitelist output desired in the logcat output.
bool is_allowed_in_logcat(enum logtype ltype) {
if ((ltype == HEADER)
@@ -48,19 +42,6 @@
return false;
}
-static bool should_write_to_kmsg() {
- // Write to kmsg if tombstoned isn't up, and we're able to do so.
- if (!android::base::GetBoolProperty("ro.debuggable", false)) {
- return false;
- }
-
- if (android::base::GetProperty("init.svc.tombstoned", "") == "running") {
- return false;
- }
-
- return true;
-}
-
__attribute__((__weak__, visibility("default")))
void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
bool write_to_tombstone = (log->tfd != -1);
@@ -68,7 +49,6 @@
&& log->crashed_tid != -1
&& log->current_tid != -1
&& (log->crashed_tid == log->current_tid);
- static bool write_to_kmsg = should_write_to_kmsg();
char buf[512];
va_list ap;
@@ -90,30 +70,6 @@
if (log->amfd_data != nullptr) {
*log->amfd_data += buf;
}
-
- if (write_to_kmsg) {
- unique_fd kmsg_fd(open("/dev/kmsg_debug", O_WRONLY | O_APPEND | O_CLOEXEC));
- if (kmsg_fd.get() >= 0) {
- // Our output might contain newlines which would otherwise be handled by the android logger.
- // Split the lines up ourselves before sending to the kernel logger.
- if (buf[len - 1] == '\n') {
- buf[len - 1] = '\0';
- }
-
- std::vector<std::string> fragments = android::base::Split(buf, "\n");
- for (const std::string& fragment : fragments) {
- static constexpr char prefix[] = "<3>DEBUG: ";
- struct iovec iov[3];
- iov[0].iov_base = const_cast<char*>(prefix);
- iov[0].iov_len = strlen(prefix);
- iov[1].iov_base = const_cast<char*>(fragment.c_str());
- iov[1].iov_len = fragment.length();
- iov[2].iov_base = const_cast<char*>("\n");
- iov[2].iov_len = 1;
- TEMP_FAILURE_RETRY(writev(kmsg_fd.get(), iov, 3));
- }
- }
- }
}
}
@@ -249,7 +205,7 @@
}
void read_with_default(const char* path, char* buf, size_t len, const char* default_value) {
- unique_fd fd(open(path, O_RDONLY | O_CLOEXEC));
+ android::base::unique_fd fd(open(path, O_RDONLY));
if (fd != -1) {
int rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, len - 1));
if (rc != -1) {
diff --git a/demangle/Android.bp b/demangle/Android.bp
index 96ab57d..ce617a7 100644
--- a/demangle/Android.bp
+++ b/demangle/Android.bp
@@ -28,6 +28,9 @@
cc_library {
name: "libdemangle",
+
+ vendor_available: true,
+
defaults: ["libdemangle_defaults"],
srcs: [
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index d0332bc..e009383 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -851,7 +851,8 @@
return FS_MGR_MNTALL_FAIL;
}
}
- if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
+ if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) ==
+ SetUpAvbHashtreeResult::kFail) {
LERROR << "Failed to set up AVB on partition: "
<< fstab->recs[i].mount_point << ", skipping!";
/* Skips mounting the device. */
@@ -859,7 +860,9 @@
}
} else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) {
int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
- if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
+ if (__android_log_is_debuggable() &&
+ (rc == FS_MGR_SETUP_VERITY_DISABLED ||
+ rc == FS_MGR_SETUP_VERITY_SKIPPED)) {
LINFO << "Verity disabled";
} else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
LERROR << "Could not set up verified partition, skipping!";
@@ -1069,7 +1072,8 @@
return FS_MGR_DOMNT_FAILED;
}
}
- if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
+ if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) ==
+ SetUpAvbHashtreeResult::kFail) {
LERROR << "Failed to set up AVB on partition: "
<< fstab->recs[i].mount_point << ", skipping!";
/* Skips mounting the device. */
@@ -1077,7 +1081,9 @@
}
} else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) {
int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
- if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
+ if (__android_log_is_debuggable() &&
+ (rc == FS_MGR_SETUP_VERITY_DISABLED ||
+ rc == FS_MGR_SETUP_VERITY_SKIPPED)) {
LINFO << "Verity disabled";
} else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
LERROR << "Could not set up verified partition, skipping!";
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 6618003..2c99aa7 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -114,7 +114,6 @@
// Reads the following values from kernel cmdline and provides the
// VerifyVbmetaImages() to verify AvbSlotVerifyData.
-// - androidboot.vbmeta.device_state
// - androidboot.vbmeta.hash_alg
// - androidboot.vbmeta.size
// - androidboot.vbmeta.digest
@@ -123,7 +122,6 @@
// The factory method to return a unique_ptr<FsManagerAvbVerifier>
static std::unique_ptr<FsManagerAvbVerifier> Create();
bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data);
- bool IsDeviceUnlocked() { return is_device_unlocked_; }
protected:
FsManagerAvbVerifier() = default;
@@ -138,7 +136,6 @@
HashAlgorithm hash_alg_;
uint8_t digest_[SHA512_DIGEST_LENGTH];
size_t vbmeta_size_;
- bool is_device_unlocked_;
};
std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() {
@@ -161,9 +158,7 @@
const std::string& key = pieces[0];
const std::string& value = pieces[1];
- if (key == "androidboot.vbmeta.device_state") {
- avb_verifier->is_device_unlocked_ = (value == "unlocked");
- } else if (key == "androidboot.vbmeta.hash_alg") {
+ if (key == "androidboot.vbmeta.hash_alg") {
hash_alg = value;
} else if (key == "androidboot.vbmeta.size") {
if (!android::base::ParseUint(value.c_str(), &avb_verifier->vbmeta_size_)) {
@@ -478,6 +473,16 @@
return true;
}
+// Orange state means the device is unlocked, see the following link for details.
+// https://source.android.com/security/verifiedboot/verified-boot#device_state
+static inline bool IsDeviceUnlocked() {
+ std::string verified_boot_state;
+ if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) {
+ return verified_boot_state == "orange";
+ }
+ return false;
+}
+
FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) {
FsManagerAvbOps avb_ops(fstab);
return DoOpen(&avb_ops);
@@ -493,12 +498,7 @@
}
FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) {
- // Gets the expected hash value of vbmeta images from kernel cmdline.
- std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create();
- if (!avb_verifier) {
- LERROR << "Failed to create FsManagerAvbVerifier";
- return nullptr;
- }
+ bool is_device_unlocked = IsDeviceUnlocked();
FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle());
if (!avb_handle) {
@@ -506,9 +506,8 @@
return nullptr;
}
- AvbSlotVerifyFlags flags = avb_verifier->IsDeviceUnlocked()
- ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
- : AVB_SLOT_VERIFY_FLAGS_NONE;
+ AvbSlotVerifyFlags flags = is_device_unlocked ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
+ : AVB_SLOT_VERIFY_FLAGS_NONE;
AvbSlotVerifyResult verify_result =
avb_ops->AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->avb_slot_data_);
@@ -526,62 +525,81 @@
// for more details.
switch (verify_result) {
case AVB_SLOT_VERIFY_RESULT_OK:
- avb_handle->status_ = kFsManagerAvbHandleSuccess;
+ avb_handle->status_ = kAvbHandleSuccess;
break;
case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
- if (!avb_verifier->IsDeviceUnlocked()) {
+ if (!is_device_unlocked) {
LERROR << "ERROR_VERIFICATION isn't allowed when the device is LOCKED";
return nullptr;
}
- avb_handle->status_ = kFsManagerAvbHandleErrorVerification;
+ avb_handle->status_ = kAvbHandleVerificationError;
break;
default:
LERROR << "avb_slot_verify failed, result: " << verify_result;
return nullptr;
}
- // Verifies vbmeta images against the digest passed from bootloader.
- if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
- LERROR << "VerifyVbmetaImages failed";
- return nullptr;
- }
-
// Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
avb_handle->avb_version_ =
android::base::StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
- // Checks whether FLAGS_HASHTREE_DISABLED is set.
+ // Checks whether FLAGS_VERIFICATION_DISABLED is set:
+ // - Only the top-level vbmeta struct is read.
+ // - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s)
+ // and AVB HASHTREE descriptor(s).
AvbVBMetaImageHeader vbmeta_header;
avb_vbmeta_image_header_to_host_byte_order(
(AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
&vbmeta_header);
+ bool verification_disabled =
+ ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
- bool hashtree_disabled =
- ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
- if (hashtree_disabled) {
- avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled;
+ if (verification_disabled) {
+ avb_handle->status_ = kAvbHandleVerificationDisabled;
+ } else {
+ // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
+ std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create();
+ if (!avb_verifier) {
+ LERROR << "Failed to create FsManagerAvbVerifier";
+ return nullptr;
+ }
+ if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
+ LERROR << "VerifyVbmetaImages failed";
+ return nullptr;
+ }
+
+ // Checks whether FLAGS_HASHTREE_DISABLED is set.
+ bool hashtree_disabled =
+ ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
+ if (hashtree_disabled) {
+ avb_handle->status_ = kAvbHandleHashtreeDisabled;
+ }
}
LINFO << "Returning avb_handle with status: " << avb_handle->status_;
return avb_handle;
}
-bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) {
- if (!fstab_entry) return false;
- if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) {
- return false;
+SetUpAvbHashtreeResult FsManagerAvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry,
+ bool wait_for_verity_dev) {
+ if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ ||
+ avb_slot_data_->num_vbmeta_images < 1) {
+ return SetUpAvbHashtreeResult::kFail;
}
- if (status_ == kFsManagerAvbHandleUninitialized) return false;
- if (status_ == kFsManagerAvbHandleHashtreeDisabled) {
- LINFO << "AVB HASHTREE disabled on:" << fstab_entry->mount_point;
- return true;
+ if (status_ == kAvbHandleHashtreeDisabled || status_ == kAvbHandleVerificationDisabled) {
+ LINFO << "AVB HASHTREE disabled on: " << fstab_entry->mount_point;
+ return SetUpAvbHashtreeResult::kDisabled;
}
- std::string partition_name(basename(fstab_entry->mount_point));
- if (!avb_validate_utf8((const uint8_t*)partition_name.c_str(), partition_name.length())) {
- LERROR << "Partition name: " << partition_name.c_str() << " is not valid UTF-8.";
- return false;
+ // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor
+ // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix.
+ std::string partition_name(basename(fstab_entry->blk_device));
+ if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) {
+ auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix());
+ if (ab_suffix != std::string::npos) {
+ partition_name.erase(ab_suffix);
+ }
}
AvbHashtreeDescriptor hashtree_descriptor;
@@ -589,13 +607,14 @@
std::string root_digest;
if (!get_hashtree_descriptor(partition_name, *avb_slot_data_, &hashtree_descriptor, &salt,
&root_digest)) {
- return false;
+ return SetUpAvbHashtreeResult::kFail;
}
// Converts HASHTREE descriptor to verity_table_params.
if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt, root_digest,
wait_for_verity_dev)) {
- return false;
+ return SetUpAvbHashtreeResult::kFail;
}
- return true;
+
+ return SetUpAvbHashtreeResult::kSuccess;
}
diff --git a/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp
index 512839b..ba1262f 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -89,6 +89,15 @@
return AVB_IO_RESULT_OK;
}
+static AvbIOResult dummy_get_size_of_partition(AvbOps* ops ATTRIBUTE_UNUSED,
+ const char* partition ATTRIBUTE_UNUSED,
+ uint64_t* out_size_num_byte) {
+ // The function is for bootloader to load entire content of AVB HASH partitions.
+ // In user-space, returns 0 as we only need to set up AVB HASHTHREE partitions.
+ *out_size_num_byte = 0;
+ return AVB_IO_RESULT_OK;
+}
+
void FsManagerAvbOps::InitializeAvbOps() {
// We only need to provide the implementation of read_from_partition()
// operation since that's all what is being used by the avb_slot_verify().
@@ -101,6 +110,7 @@
avb_ops_.validate_vbmeta_public_key = dummy_validate_vbmeta_public_key;
avb_ops_.read_is_device_unlocked = dummy_read_is_device_unlocked;
avb_ops_.get_unique_guid_for_partition = dummy_get_unique_guid_for_partition;
+ avb_ops_.get_size_of_partition = dummy_get_size_of_partition;
// Sets user_data for GetInstanceFromAvbOps() to convert it back to FsManagerAvbOps.
avb_ops_.user_data = this;
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 5fa10bc..8904995 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -738,7 +738,7 @@
// setup is needed at all.
if (!is_device_secure()) {
LINFO << "Verity setup skipped for " << mount_point;
- return FS_MGR_SETUP_VERITY_SUCCESS;
+ return FS_MGR_SETUP_VERITY_SKIPPED;
}
if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE,
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 02a22db..e033d47 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -146,6 +146,7 @@
int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);
+#define FS_MGR_SETUP_VERITY_SKIPPED (-3)
#define FS_MGR_SETUP_VERITY_DISABLED (-2)
#define FS_MGR_SETUP_VERITY_FAIL (-1)
#define FS_MGR_SETUP_VERITY_SUCCESS 0
diff --git a/fs_mgr/include/fs_mgr_avb.h b/fs_mgr/include/fs_mgr_avb.h
index bbafe1a..73a22c8 100644
--- a/fs_mgr/include/fs_mgr_avb.h
+++ b/fs_mgr/include/fs_mgr_avb.h
@@ -25,11 +25,10 @@
#include "fs_mgr.h"
-enum FsManagerAvbHandleStatus {
- kFsManagerAvbHandleUninitialized = -1,
- kFsManagerAvbHandleSuccess = 0,
- kFsManagerAvbHandleHashtreeDisabled = 1,
- kFsManagerAvbHandleErrorVerification = 2,
+enum class SetUpAvbHashtreeResult {
+ kSuccess = 0,
+ kFail,
+ kDisabled,
};
class FsManagerAvbOps;
@@ -40,8 +39,8 @@
using ByNameSymlinkMap = std::map<std::string, std::string>;
// Provides a factory method to return a unique_ptr pointing to itself and the
-// SetUpAvb() function to extract dm-verity parameters from AVB metadata to
-// load verity table into kernel through ioctl.
+// SetUpAvbHashtree() function to extract dm-verity parameters from AVB HASHTREE
+// descriptors to load verity table into kernel through ioctl.
class FsManagerAvbHandle {
public:
// The factory method to return a FsManagerAvbUniquePtr that holds
@@ -65,12 +64,22 @@
// - nullptr: any error when reading and verifying the metadata,
// e.g., I/O error, digest value mismatch, size mismatch, etc.
//
- // - a valid unique_ptr with status kFsMgrAvbHandleHashtreeDisabled:
+ // - a valid unique_ptr with status kAvbHandleHashtreeDisabled:
// to support the existing 'adb disable-verity' feature in Android.
// It's very helpful for developers to make the filesystem writable to
// allow replacing binaries on the device.
//
- // - a valid unique_ptr with status kFsMgrAvbHandleSuccess: the metadata
+ // - a valid unique_ptr with status kAvbHandleVerificationDisabled:
+ // to support 'avbctl disable-verification': only the top-level
+ // vbmeta is read, vbmeta structs in other partitions are not processed.
+ // It's needed to bypass AVB when using the generic system.img to run
+ // VTS for project Treble.
+ //
+ // - a valid unique_ptr with status kAvbHandleVerificationError:
+ // there is verification error when libavb loads vbmeta from each
+ // partition. This is only allowed when the device is unlocked.
+ //
+ // - a valid unique_ptr with status kAvbHandleSuccess: the metadata
// is verified and can be trusted.
//
static FsManagerAvbUniquePtr Open(const fstab& fstab);
@@ -79,14 +88,15 @@
// Sets up dm-verity on the given fstab entry.
// The 'wait_for_verity_dev' parameter makes this function wait for the
// verity device to get created before return.
- // Returns true if the mount point is eligible to mount, it includes:
- // - status_ is kFsMgrAvbHandleHashtreeDisabled or
- // - status_ is kFsMgrAvbHandleSuccess and sending ioctl DM_TABLE_LOAD
- // to load verity table is success.
- // Otherwise, returns false.
- bool SetUpAvb(fstab_rec* fstab_entry, bool wait_for_verity_dev);
+ //
+ // Return value:
+ // - kSuccess: successfully loads dm-verity table into kernel.
+ // - kFailed: failed to setup dm-verity, e.g., vbmeta verification error,
+ // failed to get the HASHTREE descriptor, runtime error when set up
+ // device-mapper, etc.
+ // - kDisabled: hashtree is disabled.
+ SetUpAvbHashtreeResult SetUpAvbHashtree(fstab_rec* fstab_entry, bool wait_for_verity_dev);
- bool hashtree_disabled() const { return status_ == kFsManagerAvbHandleHashtreeDisabled; }
const std::string& avb_version() const { return avb_version_; }
FsManagerAvbHandle(const FsManagerAvbHandle&) = delete; // no copy
@@ -102,11 +112,19 @@
};
private:
- FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleUninitialized) {}
+ enum AvbHandleStatus {
+ kAvbHandleSuccess = 0,
+ kAvbHandleUninitialized,
+ kAvbHandleHashtreeDisabled,
+ kAvbHandleVerificationDisabled,
+ kAvbHandleVerificationError,
+ };
+
+ FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kAvbHandleUninitialized) {}
static FsManagerAvbUniquePtr DoOpen(FsManagerAvbOps* avb_ops);
AvbSlotVerifyData* avb_slot_data_;
- FsManagerAvbHandleStatus status_;
+ AvbHandleStatus status_;
std::string avb_version_;
};
diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp
index 523e1f1..e51a06d 100644
--- a/healthd/BatteryPropertiesRegistrar.cpp
+++ b/healthd/BatteryPropertiesRegistrar.cpp
@@ -36,9 +36,19 @@
}
void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) {
- Mutex::Autolock _l(mRegistrationLock);
- for (size_t i = 0; i < mListeners.size(); i++) {
- mListeners[i]->batteryPropertiesChanged(props);
+ Vector<sp<IBatteryPropertiesListener> > listenersCopy;
+
+ // Binder currently may service an incoming oneway transaction whenever an
+ // outbound oneway call is made (if there is already a pending incoming
+ // oneway call waiting). This is considered a bug and may change in the
+ // future. For now, avoid recursive mutex lock while making outbound
+ // calls by making a local copy of the current list of listeners.
+ {
+ Mutex::Autolock _l(mRegistrationLock);
+ listenersCopy = mListeners;
+ }
+ for (size_t i = 0; i < listenersCopy.size(); i++) {
+ listenersCopy[i]->batteryPropertiesChanged(props);
}
}
diff --git a/init/Android.mk b/init/Android.mk
index 489d076..866ea34 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -9,14 +9,12 @@
-DALLOW_LOCAL_PROP_OVERRIDE=1 \
-DALLOW_PERMISSIVE_SELINUX=1 \
-DREBOOT_BOOTLOADER_ON_PANIC=1 \
- -DWORLD_WRITABLE_KMSG=1 \
-DDUMP_ON_UMOUNT_FAILURE=1
else
init_options += \
-DALLOW_LOCAL_PROP_OVERRIDE=0 \
-DALLOW_PERMISSIVE_SELINUX=0 \
-DREBOOT_BOOTLOADER_ON_PANIC=0 \
- -DWORLD_WRITABLE_KMSG=0 \
-DDUMP_ON_UMOUNT_FAILURE=0
endif
diff --git a/init/devices.cpp b/init/devices.cpp
index c52d8f8..2943fb7 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -147,21 +147,34 @@
}
}
-// Given a path that may start with a platform device, find the length of the
-// platform device prefix. If it doesn't start with a platform device, return false
-bool PlatformDeviceList::Find(const std::string& path, std::string* out_path) const {
- out_path->clear();
- // platform_devices is searched backwards, since parents are added before their children,
- // and we want to match as deep of a child as we can.
- for (auto it = platform_devices_.crbegin(); it != platform_devices_.crend(); ++it) {
- auto platform_device_path_length = it->length();
- if (platform_device_path_length < path.length() &&
- path[platform_device_path_length] == '/' &&
- android::base::StartsWith(path, it->c_str())) {
- *out_path = *it;
+// Given a path that may start with a platform device, find the parent platform device by finding a
+// parent directory with a 'subsystem' symlink that points to the platform bus.
+// If it doesn't start with a platform device, return false
+bool DeviceHandler::FindPlatformDevice(std::string path, std::string* platform_device_path) const {
+ platform_device_path->clear();
+
+ // Uevents don't contain the mount point, so we need to add it here.
+ path.insert(0, sysfs_mount_point_);
+
+ std::string directory = android::base::Dirname(path);
+
+ while (directory != "/" && directory != ".") {
+ std::string subsystem_link_path;
+ if (android::base::Realpath(directory + "/subsystem", &subsystem_link_path) &&
+ subsystem_link_path == sysfs_mount_point_ + "/bus/platform") {
+ // We need to remove the mount point that we added above before returning.
+ directory.erase(0, sysfs_mount_point_.size());
+ *platform_device_path = directory;
return true;
}
+
+ auto last_slash = path.rfind('/');
+ if (last_slash == std::string::npos) return false;
+
+ path.erase(last_slash);
+ directory = android::base::Dirname(path);
}
+
return false;
}
@@ -258,7 +271,7 @@
std::vector<std::string> DeviceHandler::GetCharacterDeviceSymlinks(const Uevent& uevent) const {
std::string parent_device;
- if (!platform_devices_.Find(uevent.path, &parent_device)) return {};
+ if (!FindPlatformDevice(uevent.path, &parent_device)) return {};
// skip path to the parent driver
std::string path = uevent.path.substr(parent_device.length());
@@ -316,7 +329,7 @@
std::string device;
std::string type;
- if (platform_devices_.Find(uevent.path, &device)) {
+ if (FindPlatformDevice(uevent.path, &device)) {
// Skip /devices/platform or /devices/ if present
static const std::string devices_platform_prefix = "/devices/platform/";
static const std::string devices_prefix = "/devices/";
@@ -388,14 +401,6 @@
}
}
-void DeviceHandler::HandlePlatformDeviceEvent(const Uevent& uevent) {
- if (uevent.action == "add") {
- platform_devices_.Add(uevent.path);
- } else if (uevent.action == "remove") {
- platform_devices_.Remove(uevent.path);
- }
-}
-
void DeviceHandler::HandleBlockDeviceEvent(const Uevent& uevent) const {
// if it's not a /dev device, nothing to do
if (uevent.major < 0 || uevent.minor < 0) return;
@@ -458,8 +463,6 @@
if (uevent.subsystem == "block") {
HandleBlockDeviceEvent(uevent);
- } else if (uevent.subsystem == "platform") {
- HandlePlatformDeviceEvent(uevent);
} else {
HandleGenericDeviceEvent(uevent);
}
@@ -472,7 +475,8 @@
sysfs_permissions_(std::move(sysfs_permissions)),
subsystems_(std::move(subsystems)),
sehandle_(selinux_android_file_context_handle()),
- skip_restorecon_(skip_restorecon) {}
+ skip_restorecon_(skip_restorecon),
+ sysfs_mount_point_("/sys") {}
DeviceHandler::DeviceHandler()
: DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
diff --git a/init/devices.h b/init/devices.h
index 09a0ce3..362c38c 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -93,20 +93,6 @@
DevnameSource devname_source_;
};
-class PlatformDeviceList {
- public:
- void Add(const std::string& path) { platform_devices_.emplace_back(path); }
- void Remove(const std::string& path) {
- auto it = std::find(platform_devices_.begin(), platform_devices_.end(), path);
- if (it != platform_devices_.end()) platform_devices_.erase(it);
- }
- bool Find(const std::string& path, std::string* out_path) const;
- auto size() const { return platform_devices_.size(); }
-
- private:
- std::vector<std::string> platform_devices_;
-};
-
class DeviceHandler {
public:
friend class DeviceHandlerTester;
@@ -119,16 +105,11 @@
void HandleDeviceEvent(const Uevent& uevent);
- void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
-
- void HandlePlatformDeviceEvent(const Uevent& uevent);
- void HandleBlockDeviceEvent(const Uevent& uevent) const;
- void HandleGenericDeviceEvent(const Uevent& uevent) const;
-
std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;
void set_skip_restorecon(bool value) { skip_restorecon_ = value; }
private:
+ bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(
const std::string& path, const std::vector<std::string>& links) const;
void MakeDevice(const std::string& path, int block, int major, int minor,
@@ -136,13 +117,17 @@
std::vector<std::string> GetCharacterDeviceSymlinks(const Uevent& uevent) const;
void HandleDevice(const std::string& action, const std::string& devpath, int block, int major,
int minor, const std::vector<std::string>& links) const;
+ void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
+
+ void HandleBlockDeviceEvent(const Uevent& uevent) const;
+ void HandleGenericDeviceEvent(const Uevent& uevent) const;
std::vector<Permissions> dev_permissions_;
std::vector<SysfsPermissions> sysfs_permissions_;
std::vector<Subsystem> subsystems_;
- PlatformDeviceList platform_devices_;
selabel_handle* sehandle_;
bool skip_restorecon_;
+ std::string sysfs_mount_point_;
};
// Exposed for testing
diff --git a/init/devices_test.cpp b/init/devices_test.cpp
index 41b101b..e1e4e49 100644
--- a/init/devices_test.cpp
+++ b/init/devices_test.cpp
@@ -16,33 +16,29 @@
#include "devices.h"
-#include <string>
-#include <vector>
-
#include <android-base/scopeguard.h>
+#include <android-base/test_utils.h>
#include <gtest/gtest.h>
+#include "util.h"
+
+using namespace std::string_literals;
+
class DeviceHandlerTester {
public:
- void AddPlatformDevice(const std::string& path) {
- Uevent uevent = {
- .action = "add", .subsystem = "platform", .path = path,
- };
- device_handler_.HandlePlatformDeviceEvent(uevent);
- }
-
- void RemovePlatformDevice(const std::string& path) {
- Uevent uevent = {
- .action = "remove", .subsystem = "platform", .path = path,
- };
- device_handler_.HandlePlatformDeviceEvent(uevent);
- }
-
- void TestGetSymlinks(const std::string& platform_device_name, const Uevent& uevent,
+ void TestGetSymlinks(const std::string& platform_device, const Uevent& uevent,
const std::vector<std::string> expected_links, bool block) {
- AddPlatformDevice(platform_device_name);
- auto platform_device_remover = android::base::make_scope_guard(
- [this, &platform_device_name]() { RemovePlatformDevice(platform_device_name); });
+ TemporaryDir fake_sys_root;
+ device_handler_.sysfs_mount_point_ = fake_sys_root.path;
+
+ std::string platform_device_dir = fake_sys_root.path + platform_device;
+ mkdir_recursive(platform_device_dir, 0777, nullptr);
+
+ std::string platform_bus = fake_sys_root.path + "/bus/platform"s;
+ mkdir_recursive(platform_bus, 0777, nullptr);
+ symlink(platform_bus.c_str(), (platform_device_dir + "/subsystem").c_str());
+
+ mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777, nullptr);
std::vector<std::string> result;
if (block) {
@@ -65,30 +61,6 @@
DeviceHandler device_handler_;
};
-TEST(device_handler, PlatformDeviceList) {
- PlatformDeviceList platform_device_list;
-
- platform_device_list.Add("/devices/platform/some_device_name");
- platform_device_list.Add("/devices/platform/some_device_name/longer");
- platform_device_list.Add("/devices/platform/other_device_name");
- EXPECT_EQ(3U, platform_device_list.size());
-
- std::string out_path;
- EXPECT_FALSE(platform_device_list.Find("/devices/platform/not_found", &out_path));
- EXPECT_EQ("", out_path);
-
- EXPECT_FALSE(platform_device_list.Find("/devices/platform/some_device_name_with_same_prefix",
- &out_path));
-
- EXPECT_TRUE(platform_device_list.Find("/devices/platform/some_device_name/longer/longer_child",
- &out_path));
- EXPECT_EQ("/devices/platform/some_device_name/longer", out_path);
-
- EXPECT_TRUE(
- platform_device_list.Find("/devices/platform/some_device_name/other_child", &out_path));
- EXPECT_EQ("/devices/platform/some_device_name", out_path);
-}
-
TEST(device_handler, get_character_device_symlinks_success) {
const char* platform_device = "/devices/platform/some_device_name";
Uevent uevent = {
diff --git a/init/init.cpp b/init/init.cpp
index ee87145..9e238d4 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -889,9 +889,6 @@
LOG(INFO) << "Running restorecon...";
selinux_android_restorecon("/dev", 0);
selinux_android_restorecon("/dev/kmsg", 0);
- if constexpr (WORLD_WRITABLE_KMSG) {
- selinux_android_restorecon("/dev/kmsg_debug", 0);
- }
selinux_android_restorecon("/dev/socket", 0);
selinux_android_restorecon("/dev/random", 0);
selinux_android_restorecon("/dev/urandom", 0);
@@ -997,13 +994,7 @@
setgroups(arraysize(groups), groups);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
-
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
-
- if constexpr (WORLD_WRITABLE_KMSG) {
- mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
- }
-
mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 0f2b1f3..3781a22 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <unistd.h>
+#include <chrono>
#include <memory>
#include <set>
#include <string>
@@ -35,6 +36,8 @@
#include "uevent_listener.h"
#include "util.h"
+using namespace std::chrono_literals;
+
// Class Declarations
// ------------------
class FirstStageMount {
@@ -49,11 +52,11 @@
bool InitDevices();
protected:
- void InitRequiredDevices();
- void InitVerityDevice(const std::string& verity_device);
+ bool InitRequiredDevices();
+ bool InitVerityDevice(const std::string& verity_device);
bool MountPartitions();
- virtual RegenerationAction UeventCallback(const Uevent& uevent);
+ virtual ListenerAction UeventCallback(const Uevent& uevent);
// Pure virtual functions.
virtual bool GetRequiredDevices() = 0;
@@ -86,7 +89,7 @@
~FirstStageMountVBootV2() override = default;
protected:
- RegenerationAction UeventCallback(const Uevent& uevent) override;
+ ListenerAction UeventCallback(const Uevent& uevent) override;
bool GetRequiredDevices() override;
bool SetUpDmVerity(fstab_rec* fstab_rec) override;
bool InitAvbHandle();
@@ -141,55 +144,60 @@
}
bool FirstStageMount::InitDevices() {
- if (!GetRequiredDevices()) return false;
-
- InitRequiredDevices();
-
- // InitRequiredDevices() will remove found partitions from required_devices_partition_names_.
- // So if it isn't empty here, it means some partitions are not found.
- if (!required_devices_partition_names_.empty()) {
- LOG(ERROR) << __FUNCTION__ << "(): partition(s) not found: "
- << android::base::Join(required_devices_partition_names_, ", ");
- return false;
- } else {
- return true;
- }
+ return GetRequiredDevices() && InitRequiredDevices();
}
// Creates devices with uevent->partition_name matching one in the member variable
// required_devices_partition_names_. Found partitions will then be removed from it
// for the subsequent member function to check which devices are NOT created.
-void FirstStageMount::InitRequiredDevices() {
+bool FirstStageMount::InitRequiredDevices() {
if (required_devices_partition_names_.empty()) {
- return;
+ return true;
}
if (need_dm_verity_) {
const std::string dm_path = "/devices/virtual/misc/device-mapper";
- uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path,
- [this, &dm_path](const Uevent& uevent) {
- if (uevent.path == dm_path) {
- device_handler_.HandleDeviceEvent(uevent);
- return RegenerationAction::kStop;
- }
- return RegenerationAction::kContinue;
- });
+ bool found = false;
+ auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
+ if (uevent.path == dm_path) {
+ device_handler_.HandleDeviceEvent(uevent);
+ found = true;
+ return ListenerAction::kStop;
+ }
+ return ListenerAction::kContinue;
+ };
+ uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
+ if (!found) {
+ uevent_listener_.Poll(dm_callback, 10s);
+ }
+ if (!found) {
+ LOG(ERROR) << "device-mapper device not found";
+ return false;
+ }
}
- uevent_listener_.RegenerateUevents(
- [this](const Uevent& uevent) { return UeventCallback(uevent); });
+ auto uevent_callback = [this](const Uevent& uevent) { return UeventCallback(uevent); };
+ uevent_listener_.RegenerateUevents(uevent_callback);
+
+ // UeventCallback() will remove found partitions from required_devices_partition_names_.
+ // So if it isn't empty here, it means some partitions are not found.
+ if (!required_devices_partition_names_.empty()) {
+ uevent_listener_.Poll(uevent_callback, 10s);
+ }
+
+ if (!required_devices_partition_names_.empty()) {
+ LOG(ERROR) << __PRETTY_FUNCTION__ << ": partition(s) not found: "
+ << android::base::Join(required_devices_partition_names_, ", ");
+ return false;
+ }
+
+ return true;
}
-RegenerationAction FirstStageMount::UeventCallback(const Uevent& uevent) {
- // We need platform devices to create symlinks.
- if (uevent.subsystem == "platform") {
- device_handler_.HandleDeviceEvent(uevent);
- return RegenerationAction::kContinue;
- }
-
+ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent) {
// Ignores everything that is not a block device.
if (uevent.subsystem != "block") {
- return RegenerationAction::kContinue;
+ return ListenerAction::kContinue;
}
if (!uevent.partition_name.empty()) {
@@ -198,34 +206,46 @@
// suffix when A/B is used.
auto iter = required_devices_partition_names_.find(uevent.partition_name);
if (iter != required_devices_partition_names_.end()) {
- LOG(VERBOSE) << __FUNCTION__ << "(): found partition: " << *iter;
+ LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
required_devices_partition_names_.erase(iter);
device_handler_.HandleDeviceEvent(uevent);
if (required_devices_partition_names_.empty()) {
- return RegenerationAction::kStop;
+ return ListenerAction::kStop;
} else {
- return RegenerationAction::kContinue;
+ return ListenerAction::kContinue;
}
}
}
// Not found a partition or find an unneeded partition, continue to find others.
- return RegenerationAction::kContinue;
+ return ListenerAction::kContinue;
}
// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX.
-void FirstStageMount::InitVerityDevice(const std::string& verity_device) {
+bool FirstStageMount::InitVerityDevice(const std::string& verity_device) {
const std::string device_name(basename(verity_device.c_str()));
const std::string syspath = "/sys/block/" + device_name;
+ bool found = false;
- uevent_listener_.RegenerateUeventsForPath(
- syspath, [&device_name, &verity_device, this](const Uevent& uevent) {
- if (uevent.device_name == device_name) {
- LOG(VERBOSE) << "Creating dm-verity device : " << verity_device;
- device_handler_.HandleDeviceEvent(uevent);
- return RegenerationAction::kStop;
- }
- return RegenerationAction::kContinue;
- });
+ auto verity_callback = [&device_name, &verity_device, this, &found](const Uevent& uevent) {
+ if (uevent.device_name == device_name) {
+ LOG(VERBOSE) << "Creating dm-verity device : " << verity_device;
+ device_handler_.HandleDeviceEvent(uevent);
+ found = true;
+ return ListenerAction::kStop;
+ }
+ return ListenerAction::kContinue;
+ };
+
+ uevent_listener_.RegenerateUeventsForPath(syspath, verity_callback);
+ if (!found) {
+ uevent_listener_.Poll(verity_callback, 10s);
+ }
+ if (!found) {
+ LOG(ERROR) << "dm-verity device not found";
+ return false;
+ }
+
+ return true;
}
bool FirstStageMount::MountPartitions() {
@@ -286,14 +306,18 @@
bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) {
if (fs_mgr_is_verified(fstab_rec)) {
int ret = fs_mgr_setup_verity(fstab_rec, false /* wait_for_verity_dev */);
- if (ret == FS_MGR_SETUP_VERITY_DISABLED) {
- LOG(INFO) << "Verity disabled for '" << fstab_rec->mount_point << "'";
- } else if (ret == FS_MGR_SETUP_VERITY_SUCCESS) {
- // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX".
- // Needs to create it because ueventd isn't started in init first stage.
- InitVerityDevice(fstab_rec->blk_device);
- } else {
- return false;
+ switch (ret) {
+ case FS_MGR_SETUP_VERITY_SKIPPED:
+ case FS_MGR_SETUP_VERITY_DISABLED:
+ LOG(INFO) << "Verity disabled/skipped for '" << fstab_rec->mount_point << "'";
+ return true;
+ case FS_MGR_SETUP_VERITY_SUCCESS:
+ // The exact block device name (fstab_rec->blk_device) is changed to
+ // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
+ // first stage.
+ return InitVerityDevice(fstab_rec->blk_device);
+ default:
+ return false;
}
}
return true; // Returns true to mount the partition.
@@ -351,7 +375,7 @@
return true;
}
-RegenerationAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) {
+ListenerAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) {
// Check if this uevent corresponds to one of the required partitions and store its symlinks if
// so, in order to create FsManagerAvbHandle later.
// Note that the parent callback removes partitions from the list of required partitions
@@ -382,14 +406,18 @@
bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) {
if (fs_mgr_is_avb(fstab_rec)) {
if (!InitAvbHandle()) return false;
- if (avb_handle_->hashtree_disabled()) {
- LOG(INFO) << "avb hashtree disabled for '" << fstab_rec->mount_point << "'";
- } else if (avb_handle_->SetUpAvb(fstab_rec, false /* wait_for_verity_dev */)) {
- // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX".
- // Needs to create it because ueventd isn't started in init first stage.
- InitVerityDevice(fstab_rec->blk_device);
- } else {
- return false;
+ SetUpAvbHashtreeResult hashtree_result =
+ avb_handle_->SetUpAvbHashtree(fstab_rec, false /* wait_for_verity_dev */);
+ switch (hashtree_result) {
+ case SetUpAvbHashtreeResult::kDisabled:
+ return true; // Returns true to mount the partition.
+ case SetUpAvbHashtreeResult::kSuccess:
+ // The exact block device name (fstab_rec->blk_device) is changed to
+ // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
+ // first stage.
+ return InitVerityDevice(fstab_rec->blk_device);
+ default:
+ return false;
}
}
return true; // Returns true to mount the partition.
diff --git a/init/service.cpp b/init/service.cpp
index 7c931da..1a6474b 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -209,17 +209,6 @@
}
void Service::KillProcessGroup(int signal) {
- // We ignore reporting errors of ESRCH as this commonly happens in the below case,
- // 1) Terminate() is called, which sends SIGTERM to the process
- // 2) The process successfully exits
- // 3) ReapOneProcess() is called, which calls waitpid(-1, ...) which removes the pid entry.
- // 4) Reap() is called, which sends SIGKILL, but the pid no longer exists.
- // TODO: sigaction for SIGCHLD reports the pid of the exiting process,
- // we should do this kill with that pid first before calling waitpid().
- if (kill(-pid_, signal) == -1 && errno != ESRCH) {
- PLOG(ERROR) << "kill(" << pid_ << ", " << signal << ") failed";
- }
-
// If we've already seen a successful result from killProcessGroup*(), then we have removed
// the cgroup already and calling these functions a second time will simply result in an error.
// This is true regardless of which signal was sent.
diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp
index 01b8250..923fa8e 100644
--- a/init/uevent_listener.cpp
+++ b/init/uevent_listener.cpp
@@ -121,8 +121,8 @@
// make sure we don't overrun the socket's buffer.
//
-RegenerationAction UeventListener::RegenerateUeventsForDir(DIR* d,
- RegenerateCallback callback) const {
+ListenerAction UeventListener::RegenerateUeventsForDir(DIR* d,
+ const ListenerCallback& callback) const {
int dfd = dirfd(d);
int fd = openat(dfd, "uevent", O_WRONLY);
@@ -132,7 +132,7 @@
Uevent uevent;
while (ReadUevent(&uevent)) {
- if (callback(uevent) == RegenerationAction::kStop) return RegenerationAction::kStop;
+ if (callback(uevent) == ListenerAction::kStop) return ListenerAction::kStop;
}
}
@@ -147,49 +147,67 @@
if (d2 == 0) {
close(fd);
} else {
- if (RegenerateUeventsForDir(d2.get(), callback) == RegenerationAction::kStop) {
- return RegenerationAction::kStop;
+ if (RegenerateUeventsForDir(d2.get(), callback) == ListenerAction::kStop) {
+ return ListenerAction::kStop;
}
}
}
// default is always to continue looking for uevents
- return RegenerationAction::kContinue;
+ return ListenerAction::kContinue;
}
-RegenerationAction UeventListener::RegenerateUeventsForPath(const std::string& path,
- RegenerateCallback callback) const {
+ListenerAction UeventListener::RegenerateUeventsForPath(const std::string& path,
+ const ListenerCallback& callback) const {
std::unique_ptr<DIR, decltype(&closedir)> d(opendir(path.c_str()), closedir);
- if (!d) return RegenerationAction::kContinue;
+ if (!d) return ListenerAction::kContinue;
return RegenerateUeventsForDir(d.get(), callback);
}
const char* kRegenerationPaths[] = {"/sys/class", "/sys/block", "/sys/devices"};
-void UeventListener::RegenerateUevents(RegenerateCallback callback) const {
+void UeventListener::RegenerateUevents(const ListenerCallback& callback) const {
for (const auto path : kRegenerationPaths) {
- if (RegenerateUeventsForPath(path, callback) == RegenerationAction::kStop) return;
+ if (RegenerateUeventsForPath(path, callback) == ListenerAction::kStop) return;
}
}
-void UeventListener::DoPolling(PollCallback callback) const {
+void UeventListener::Poll(const ListenerCallback& callback,
+ const std::optional<std::chrono::milliseconds> relative_timeout) const {
+ using namespace std::chrono;
+
pollfd ufd;
ufd.events = POLLIN;
ufd.fd = device_fd_;
+ auto start_time = steady_clock::now();
+
while (true) {
ufd.revents = 0;
- int nr = poll(&ufd, 1, -1);
- if (nr <= 0) {
+
+ int timeout_ms = -1;
+ if (relative_timeout) {
+ auto now = steady_clock::now();
+ auto time_elapsed = duration_cast<milliseconds>(now - start_time);
+ if (time_elapsed > *relative_timeout) return;
+
+ auto remaining_timeout = *relative_timeout - time_elapsed;
+ timeout_ms = remaining_timeout.count();
+ }
+
+ int nr = poll(&ufd, 1, timeout_ms);
+ if (nr == 0) return;
+ if (nr < 0) {
+ PLOG(ERROR) << "poll() of uevent socket failed, continuing";
continue;
}
if (ufd.revents & POLLIN) {
- // We're non-blocking, so if we receive a poll event keep processing until there
+ // We're non-blocking, so if we receive a poll event keep processing until
// we have exhausted all uevent messages.
Uevent uevent;
while (ReadUevent(&uevent)) {
- callback(uevent);
+ if (callback(uevent) == ListenerAction::kStop) return;
}
}
}
diff --git a/init/uevent_listener.h b/init/uevent_listener.h
index 8e6f3b4..1964688 100644
--- a/init/uevent_listener.h
+++ b/init/uevent_listener.h
@@ -19,7 +19,9 @@
#include <dirent.h>
+#include <chrono>
#include <functional>
+#include <optional>
#include <android-base/unique_fd.h>
@@ -27,13 +29,12 @@
#define UEVENT_MSG_LEN 2048
-enum class RegenerationAction {
+enum class ListenerAction {
kStop = 0, // Stop regenerating uevents as we've handled the one(s) we're interested in.
kContinue, // Continue regenerating uevents as we haven't seen the one(s) we're interested in.
};
-using RegenerateCallback = std::function<RegenerationAction(const Uevent&)>;
-using PollCallback = std::function<void(const Uevent&)>;
+using ListenerCallback = std::function<ListenerAction(const Uevent&)>;
extern const char* kRegenerationPaths[3];
@@ -41,14 +42,15 @@
public:
UeventListener();
- void RegenerateUevents(RegenerateCallback callback) const;
- RegenerationAction RegenerateUeventsForPath(const std::string& path,
- RegenerateCallback callback) const;
- void DoPolling(PollCallback callback) const;
+ void RegenerateUevents(const ListenerCallback& callback) const;
+ ListenerAction RegenerateUeventsForPath(const std::string& path,
+ const ListenerCallback& callback) const;
+ void Poll(const ListenerCallback& callback,
+ const std::optional<std::chrono::milliseconds> relative_timeout = {}) const;
private:
bool ReadUevent(Uevent* uevent) const;
- RegenerationAction RegenerateUeventsForDir(DIR* d, RegenerateCallback callback) const;
+ ListenerAction RegenerateUeventsForDir(DIR* d, const ListenerCallback& callback) const;
android::base::unique_fd device_fd_;
};
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 31e4106..ff64e8e 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -128,15 +128,7 @@
void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) {
for (unsigned int i = process_num; i < uevent_queue_.size(); i += total_processes) {
auto& uevent = uevent_queue_[i];
- if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
- device_handler_.FixupSysPermissions(uevent.path, uevent.subsystem);
- }
-
- if (uevent.subsystem == "block") {
- device_handler_.HandleBlockDeviceEvent(uevent);
- } else {
- device_handler_.HandleGenericDeviceEvent(uevent);
- }
+ device_handler_.HandleDeviceEvent(uevent);
}
_exit(EXIT_SUCCESS);
}
@@ -145,16 +137,8 @@
uevent_listener_.RegenerateUevents([this](const Uevent& uevent) {
HandleFirmwareEvent(uevent);
- // This is the one mutable part of DeviceHandler, in which platform devices are
- // added to a vector for later reference. Since there is no communication after
- // fork()'ing subprocess handlers, all platform devices must be in the vector before
- // we fork, and therefore they must be handled in this loop.
- if (uevent.subsystem == "platform") {
- device_handler_.HandlePlatformDeviceEvent(uevent);
- }
-
uevent_queue_.emplace_back(std::move(uevent));
- return RegenerationAction::kContinue;
+ return ListenerAction::kContinue;
});
}
@@ -284,9 +268,10 @@
cold_boot.Run();
}
- uevent_listener.DoPolling([&device_handler](const Uevent& uevent) {
+ uevent_listener.Poll([&device_handler](const Uevent& uevent) {
HandleFirmwareEvent(uevent);
device_handler.HandleDeviceEvent(uevent);
+ return ListenerAction::kContinue;
});
return 0;
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index 1b47e0a..1eab46c 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -251,7 +251,9 @@
void FuseBuffer::HandleNotImpl() {
LOG(VERBOSE) << "NOTIMPL op=" << request.header.opcode << " uniq="
<< request.header.unique << " nid=" << request.header.nodeid;
- const uint64_t unique = request.header.unique;
+ // Add volatile as a workaround for compiler issue which removes the temporary
+ // variable.
+ const volatile uint64_t unique = request.header.unique;
response.Reset(0, -ENOSYS, unique);
}
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index 4269eaa..cdac76b 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -23,7 +23,6 @@
cc_library_shared {
name: "libmemunreachable",
- vendor_available: true,
defaults: ["libmemunreachable_defaults"],
srcs: [
"Allocator.cpp",
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 27b4065..f5d4e1c 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -27,10 +27,12 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include <chrono>
#include <memory>
#include <mutex>
+#include <set>
#include <thread>
#include <android-base/logging.h>
@@ -258,6 +260,12 @@
return -errno;
}
+ // We separate all of the pids in the cgroup into those pids that are also the leaders of
+ // process groups (stored in the pgids set) and those that are not (stored in the pids set).
+ std::set<pid_t> pgids;
+ pgids.emplace(initialPid);
+ std::set<pid_t> pids;
+
int ret;
pid_t pid;
int processes = 0;
@@ -269,8 +277,40 @@
LOG(WARNING) << "Yikes, we've been told to kill pid 0! How about we don't do that?";
continue;
}
+ pid_t pgid = getpgid(pid);
+ if (pgid == -1) PLOG(ERROR) << "getpgid(" << pid << ") failed";
+ if (pgid == pid) {
+ pgids.emplace(pid);
+ } else {
+ pids.emplace(pid);
+ }
+ }
+
+ // Erase all pids that will be killed when we kill the process groups.
+ for (auto it = pids.begin(); it != pids.end();) {
+ pid_t pgid = getpgid(pid);
+ if (pgids.count(pgid) == 1) {
+ it = pids.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+ // Kill all process groups.
+ for (const auto pgid : pgids) {
+ LOG(VERBOSE) << "Killing process group " << -pgid << " in uid " << uid
+ << " as part of process cgroup " << initialPid;
+
+ if (kill(-pgid, signal) == -1) {
+ PLOG(WARNING) << "kill(" << -pgid << ", " << signal << ") failed";
+ }
+ }
+
+ // Kill remaining pids.
+ for (const auto pid : pids) {
LOG(VERBOSE) << "Killing pid " << pid << " in uid " << uid << " as part of process cgroup "
<< initialPid;
+
if (kill(pid, signal) == -1) {
PLOG(WARNING) << "kill(" << pid << ", " << signal << ") failed";
}
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 621b632..d64eb35 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -63,7 +63,7 @@
namespace.sphal.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libvndksupport.so
# WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line.
-namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so
+namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so
# Renderscript gets separate namespace
namespace.sphal.link.rs.shared_libs = libRS_internal.so
@@ -85,7 +85,7 @@
namespace.rs.links = default,vndk
namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so
-namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so
+namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so
###############################################################################
# "vndk" namespace
@@ -103,7 +103,7 @@
# to the default namespace. This is possible since their ABI is stable across
# Android releases.
namespace.vndk.links = default
-namespace.vndk.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so
+namespace.vndk.link.default.shared_libs = android.hidl.memory@1.0-impl.so:libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so
[vendor]
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 4f4fc5d..6d35fed 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -3,6 +3,7 @@
required: [
"bzip2",
"grep",
+ "grep_vendor",
"gzip",
"mkshrc",
"mkshrc_vendor",
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index 1c9fb20..8db8327 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -28,8 +28,8 @@
}
// We build BSD grep separately, so it can provide egrep and fgrep too.
-cc_binary {
- name: "grep",
+cc_defaults {
+ name: "grep_common",
srcs: [
"upstream-netbsd/usr.bin/grep/fastgrep.c",
"upstream-netbsd/usr.bin/grep/file.c",
@@ -40,5 +40,19 @@
cflags: common_cflags,
local_include_dirs: ["upstream-netbsd/include/"],
symlinks: ["egrep", "fgrep"],
+}
+cc_binary {
+ name: "grep",
+ defaults: ["grep_common"],
+}
+
+// Build vendor grep.
+// TODO: Add vendor_available to "grep" module and remove "grep_vendor" module
+// when vendor_available is fully supported.
+cc_binary {
+ name: "grep_vendor",
+ stem: "grep",
+ vendor: true,
+ defaults: ["grep_common"],
}