Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dcd1f1aa authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

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

Change-Id: I06d1d012a71a678964eb5c005f1dc66cb623db56
parents bb236cd9 7043054d
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -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;
    }

+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ class SnapuserdSelinuxHelper final {
  private:
    void RelaunchFirstStageSnapuserd();
    void ExecSnapuserd();
    bool TestSnapuserdIsReady();

    std::unique_ptr<SnapshotManager> sm_;
    BlockDevInitializer block_dev_init_;