Merge cherrypicks of [16718400] into sc-d2-release.

Change-Id: I199c886a26c85b51d769f9f3006bd60054df2e3b
This commit is contained in:
Android Build Coastguard Worker 2022-01-26 07:26:59 +00:00
commit 25d994b1ce
2 changed files with 59 additions and 0 deletions

View File

@ -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;
}

View File

@ -51,6 +51,7 @@ class SnapuserdSelinuxHelper final {
private:
void RelaunchFirstStageSnapuserd();
void ExecSnapuserd();
bool TestSnapuserdIsReady();
std::unique_ptr<SnapshotManager> sm_;
BlockDevInitializer block_dev_init_;