diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-01-26 21:40:01 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-01-26 21:40:01 +0000 |
commit | dcd1f1aae4eee33c8556018558c82f69e2e0a5f2 (patch) | |
tree | a282fa8bc795d1e9960f5be47c43915b9f5a7056 | |
parent | bb236cd9d6425595c136e90407e1f137b4c28ccd (diff) | |
parent | 7043054dfee9e29cd9a77903d7d63ed2a07e1707 (diff) | |
download | core-android12L-s1-release.tar.gz |
Merge cherrypicks of [16718400] into sc-v2-release.android-vts-12.1_r1android-platform-12.1.0_r3android-platform-12.1.0_r2android-platform-12.1.0_r1android-cts-12.1_r1android-12.1.0_r6android-12.1.0_r5android-12.1.0_r4android-12.1.0_r3android-12.1.0_r27android-12.1.0_r2android-12.1.0_r1android12L-s1-releaseandroid12L-release
Change-Id: I06d1d012a71a678964eb5c005f1dc66cb623db56
-rw-r--r-- | init/snapuserd_transition.cpp | 58 | ||||
-rw-r--r-- | init/snapuserd_transition.h | 1 |
2 files changed, 59 insertions, 0 deletions
diff --git a/init/snapuserd_transition.cpp b/init/snapuserd_transition.cpp index 40467b7d3..7fd3f65ca 100644 --- a/init/snapuserd_transition.cpp +++ b/init/snapuserd_transition.cpp @@ -32,6 +32,7 @@ #include <android-base/strings.h> #include <android-base/unique_fd.h> #include <cutils/sockets.h> +#include <fs_avb/fs_avb.h> #include <libsnapshot/snapshot.h> #include <libsnapshot/snapuserd_client.h> #include <private/android_filesystem_config.h> @@ -227,6 +228,56 @@ void SnapuserdSelinuxHelper::FinishTransition() { } } +/* + * Before starting init second stage, we will wait + * for snapuserd daemon to be up and running; bionic libc + * may read /system/etc/selinux/plat_property_contexts file + * before invoking main() function. This will happen if + * init initializes property during second stage. Any access + * to /system without snapuserd daemon will lead to a deadlock. + * + * Thus, we do a simple probe by reading system partition. This + * read will eventually be serviced by daemon confirming that + * daemon is up and running. Furthermore, we are still in the kernel + * domain and sepolicy has not been enforced yet. Thus, access + * to these device mapper block devices are ok even though + * we may see audit logs. + */ +bool SnapuserdSelinuxHelper::TestSnapuserdIsReady() { + std::string dev = "/dev/block/mapper/system"s + fs_mgr_get_slot_suffix(); + android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_DIRECT)); + if (fd < 0) { + PLOG(ERROR) << "open " << dev << " failed"; + return false; + } + + void* addr; + ssize_t page_size = getpagesize(); + if (posix_memalign(&addr, page_size, page_size) < 0) { + PLOG(ERROR) << "posix_memalign with page size " << page_size; + return false; + } + + std::unique_ptr<void, decltype(&::free)> buffer(addr, ::free); + + int iter = 0; + while (iter < 10) { + ssize_t n = TEMP_FAILURE_RETRY(pread(fd.get(), buffer.get(), page_size, 0)); + if (n < 0) { + // Wait for sometime before retry + std::this_thread::sleep_for(100ms); + } else if (n == page_size) { + return true; + } else { + LOG(ERROR) << "pread returned: " << n << " from: " << dev << " expected: " << page_size; + } + + iter += 1; + } + + return false; +} + void SnapuserdSelinuxHelper::RelaunchFirstStageSnapuserd() { auto fd = GetRamdiskSnapuserdFd(); if (!fd) { @@ -248,6 +299,13 @@ void SnapuserdSelinuxHelper::RelaunchFirstStageSnapuserd() { setenv(kSnapuserdFirstStagePidVar, std::to_string(pid).c_str(), 1); LOG(INFO) << "Relaunched snapuserd with pid: " << pid; + + if (!TestSnapuserdIsReady()) { + PLOG(FATAL) << "snapuserd daemon failed to launch"; + } else { + LOG(INFO) << "snapuserd daemon is up and running"; + } + return; } diff --git a/init/snapuserd_transition.h b/init/snapuserd_transition.h index a5ab652b7..757af1377 100644 --- a/init/snapuserd_transition.h +++ b/init/snapuserd_transition.h @@ -51,6 +51,7 @@ class SnapuserdSelinuxHelper final { private: void RelaunchFirstStageSnapuserd(); void ExecSnapuserd(); + bool TestSnapuserdIsReady(); std::unique_ptr<SnapshotManager> sm_; BlockDevInitializer block_dev_init_; |