summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-01-26 07:26:59 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-01-26 07:26:59 +0000
commit25d994b1ceaa9b6e12553708c98232f6e1345e6e (patch)
treea282fa8bc795d1e9960f5be47c43915b9f5a7056
parent73d1c56fba092ccbcf9aa236d656af6631fd6e7c (diff)
parentf53f371806d307845e0c35fa1da31b1cd2228bc4 (diff)
downloadcore-android12L-d2-s6-release.tar.gz
Change-Id: I199c886a26c85b51d769f9f3006bd60054df2e3b
-rw-r--r--init/snapuserd_transition.cpp58
-rw-r--r--init/snapuserd_transition.h1
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_;