diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-01-26 07:26:59 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-01-26 07:26:59 +0000 |
commit | 25d994b1ceaa9b6e12553708c98232f6e1345e6e (patch) | |
tree | a282fa8bc795d1e9960f5be47c43915b9f5a7056 | |
parent | 73d1c56fba092ccbcf9aa236d656af6631fd6e7c (diff) | |
parent | f53f371806d307845e0c35fa1da31b1cd2228bc4 (diff) | |
download | core-android12L-d2-s5-release.tar.gz |
Merge cherrypicks of [16718400] into sc-d2-release.android-12.1.0_r26android-12.1.0_r25android-12.1.0_r24android-12.1.0_r23android-12.1.0_r18android-12.1.0_r17android-12.1.0_r16android-12.1.0_r15android-12.1.0_r14android-12.1.0_r13android-12.1.0_r12android12L-d2-s8-releaseandroid12L-d2-s7-releaseandroid12L-d2-s6-releaseandroid12L-d2-s5-releaseandroid12L-d2-s4-releaseandroid12L-d2-s3-releaseandroid12L-d2-s2-releaseandroid12L-d2-s1-releaseandroid12L-d2-release
Change-Id: I199c886a26c85b51d769f9f3006bd60054df2e3b
-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_; |