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

Commit 889b4468 authored by Akilesh Kailash's avatar Akilesh Kailash Committed by Gerrit Code Review
Browse files

Merge "init: Detach daemon only after sepolicy is loaded"

parents 9b123de8 035e557f
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -332,10 +332,13 @@ class SnapshotManager final : public ISnapshotManager {
    // Helper function for second stage init to restorecon on the rollback indicator.
    static std::string GetGlobalRollbackIndicatorPath();

    // Detach dm-user devices from the current snapuserd, and populate
    // |snapuserd_argv| with the necessary arguments to restart snapuserd
    // and reattach them.
    bool DetachSnapuserdForSelinux(std::vector<std::string>* snapuserd_argv);
    // Populate |snapuserd_argv| with the necessary arguments to restart snapuserd
    // after loading selinux policy.
    bool PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv);

    // Detach dm-user devices from the first stage snapuserd. Load
    // new dm-user tables after loading selinux policy.
    bool DetachFirstStageSnapuserdForSelinux();

    // Perform the transition from the selinux stage of snapuserd into the
    // second-stage of snapuserd. This process involves re-creating the dm-user
+76 −15
Original line number Diff line number Diff line
@@ -1746,13 +1746,6 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,

        auto misc_name = user_cow_name;

        DmTable table;
        table.Emplace<DmTargetUser>(0, target.spec.length, misc_name);
        if (!dm_.LoadTableAndActivate(user_cow_name, table)) {
            LOG(ERROR) << "Unable to swap tables for " << misc_name;
            continue;
        }

        std::string source_device_name;
        if (snapshot_status.old_partition_size() > 0) {
            source_device_name = GetSourceDeviceName(snapshot);
@@ -1780,13 +1773,6 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
            continue;
        }

        // Wait for ueventd to acknowledge and create the control device node.
        std::string control_device = "/dev/dm-user/" + misc_name;
        if (!WaitForDevice(control_device, 10s)) {
            LOG(ERROR) << "dm-user control device no found:  " << misc_name;
            continue;
        }

        if (transition == InitTransition::SELINUX_DETACH) {
            if (!UpdateUsesUserSnapshots(lock.get())) {
                auto message = misc_name + "," + cow_image_device + "," + source_device;
@@ -1804,6 +1790,20 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
            continue;
        }

        DmTable table;
        table.Emplace<DmTargetUser>(0, target.spec.length, misc_name);
        if (!dm_.LoadTableAndActivate(user_cow_name, table)) {
            LOG(ERROR) << "Unable to swap tables for " << misc_name;
            continue;
        }

        // Wait for ueventd to acknowledge and create the control device node.
        std::string control_device = "/dev/dm-user/" + misc_name;
        if (!WaitForDevice(control_device, 10s)) {
            LOG(ERROR) << "dm-user control device no found:  " << misc_name;
            continue;
        }

        uint64_t base_sectors;
        if (!UpdateUsesUserSnapshots(lock.get())) {
            base_sectors =
@@ -4136,10 +4136,71 @@ bool SnapshotManager::IsSnapuserdRequired() {
    return status.state() != UpdateState::None && status.using_snapuserd();
}

bool SnapshotManager::DetachSnapuserdForSelinux(std::vector<std::string>* snapuserd_argv) {
bool SnapshotManager::PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv) {
    return PerformInitTransition(InitTransition::SELINUX_DETACH, snapuserd_argv);
}

bool SnapshotManager::DetachFirstStageSnapuserdForSelinux() {
    LOG(INFO) << "Detaching first stage snapuserd";

    auto lock = LockExclusive();
    if (!lock) return false;

    std::vector<std::string> snapshots;
    if (!ListSnapshots(lock.get(), &snapshots)) {
        LOG(ERROR) << "Failed to list snapshots.";
        return false;
    }

    size_t num_cows = 0;
    size_t ok_cows = 0;
    for (const auto& snapshot : snapshots) {
        std::string user_cow_name = GetDmUserCowName(snapshot, GetSnapshotDriver(lock.get()));

        if (dm_.GetState(user_cow_name) == DmDeviceState::INVALID) {
            continue;
        }

        DeviceMapper::TargetInfo target;
        if (!GetSingleTarget(user_cow_name, TableQuery::Table, &target)) {
            continue;
        }

        auto target_type = DeviceMapper::GetTargetType(target.spec);
        if (target_type != "user") {
            LOG(ERROR) << "Unexpected target type for " << user_cow_name << ": " << target_type;
            continue;
        }

        num_cows++;
        auto misc_name = user_cow_name;

        DmTable table;
        table.Emplace<DmTargetUser>(0, target.spec.length, misc_name);
        if (!dm_.LoadTableAndActivate(user_cow_name, table)) {
            LOG(ERROR) << "Unable to swap tables for " << misc_name;
            continue;
        }

        // Wait for ueventd to acknowledge and create the control device node.
        std::string control_device = "/dev/dm-user/" + misc_name;
        if (!WaitForDevice(control_device, 10s)) {
            LOG(ERROR) << "dm-user control device no found:  " << misc_name;
            continue;
        }

        ok_cows++;
        LOG(INFO) << "control device is ready: " << control_device;
    }

    if (ok_cows != num_cows) {
        LOG(ERROR) << "Could not transition all snapuserd consumers.";
        return false;
    }

    return true;
}

bool SnapshotManager::PerformSecondStageInitTransition() {
    return PerformInitTransition(InitTransition::SECOND_STAGE);
}
+7 −4
Original line number Diff line number Diff line
@@ -226,12 +226,9 @@ void SnapuserdSelinuxHelper::StartTransition() {

    argv_.emplace_back("snapuserd");
    argv_.emplace_back("-no_socket");
    if (!sm_->DetachSnapuserdForSelinux(&argv_)) {
    if (!sm_->PrepareSnapuserdArgsForSelinux(&argv_)) {
        LOG(FATAL) << "Could not perform selinux transition";
    }

    // Make sure the process is gone so we don't have any selinux audits.
    KillFirstStageSnapuserd(old_pid_);
}

void SnapuserdSelinuxHelper::FinishTransition() {
@@ -301,6 +298,12 @@ bool SnapuserdSelinuxHelper::TestSnapuserdIsReady() {
}

void SnapuserdSelinuxHelper::RelaunchFirstStageSnapuserd() {
    if (!sm_->DetachFirstStageSnapuserdForSelinux()) {
        LOG(FATAL) << "Could not perform selinux transition";
    }

    KillFirstStageSnapuserd(old_pid_);

    auto fd = GetRamdiskSnapuserdFd();
    if (!fd) {
        LOG(FATAL) << "Environment variable " << kSnapuserdFirstStageFdVar << " was not set!";