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

Commit dda9cbb3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Use precompiled sepolicy when available"

parents 4e5e797d 2d19aeb1
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -119,7 +119,14 @@ LOCAL_REQUIRED_MODULES += \
    mapping_sepolicy.cil \
    nonplat_sepolicy.cil \
    plat_sepolicy.cil \
    plat_sepolicy.cil.sha256 \
    secilc

# Include precompiled policy, unless told otherwise
ifneq ($(PRODUCT_PRECOMPILED_SEPOLICY),false)
LOCAL_REQUIRED_MODULES += precompiled_sepolicy precompiled_sepolicy.plat.sha256
endif

else
# Use monolithic SELinux policy
LOCAL_REQUIRED_MODULES += sepolicy
+54 −0
Original line number Diff line number Diff line
@@ -715,6 +715,44 @@ static bool fork_execve_and_wait_for_completion(const char* filename, char* cons
    }
}

static bool read_first_line(const char* file, std::string* line) {
    line->clear();

    std::string contents;
    if (!android::base::ReadFileToString(file, &contents, true /* follow symlinks */)) {
        return false;
    }
    std::istringstream in(contents);
    std::getline(in, *line);
    return true;
}

static bool selinux_find_precompiled_split_policy(std::string* file) {
    file->clear();

    static constexpr const char precompiled_sepolicy[] = "/vendor/etc/selinux/precompiled_sepolicy";
    if (access(precompiled_sepolicy, R_OK) == -1) {
        return false;
    }
    std::string actual_plat_id;
    if (!read_first_line("/system/etc/selinux/plat_sepolicy.cil.sha256", &actual_plat_id)) {
        PLOG(INFO) << "Failed to read /system/etc/selinux/plat_sepolicy.cil.sha256";
        return false;
    }
    std::string precompiled_plat_id;
    if (!read_first_line("/vendor/etc/selinux/precompiled_sepolicy.plat.sha256",
                         &precompiled_plat_id)) {
        PLOG(INFO) << "Failed to read /vendor/etc/selinux/precompiled_sepolicy.plat.sha256";
        return false;
    }
    if ((actual_plat_id.empty()) || (actual_plat_id != precompiled_plat_id)) {
        return false;
    }

    *file = precompiled_sepolicy;
    return true;
}

static constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil";

static bool selinux_is_split_policy_device() { return access(plat_policy_cil_file, R_OK) != -1; }
@@ -734,6 +772,22 @@ static bool selinux_load_split_policy() {
    // secilc is invoked to compile the above three policy files into a single monolithic policy
    // file. This file is then loaded into the kernel.

    // Load precompiled policy from vendor image, if a matching policy is found there. The policy
    // must match the platform policy on the system image.
    std::string precompiled_sepolicy_file;
    if (selinux_find_precompiled_split_policy(&precompiled_sepolicy_file)) {
        android::base::unique_fd fd(
            open(precompiled_sepolicy_file.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY));
        if (fd != -1) {
            if (selinux_android_load_policy_from_fd(fd, precompiled_sepolicy_file.c_str()) < 0) {
                LOG(ERROR) << "Failed to load SELinux policy from " << precompiled_sepolicy_file;
                return false;
            }
            return true;
        }
    }
    // No suitable precompiled policy could be loaded

    LOG(INFO) << "Compiling SELinux policy";

    // We store the output of the compilation on /dev because this is the most convenient tmpfs