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

Commit f9ac2fa7 authored by Alex Klyubin's avatar Alex Klyubin Committed by android-build-merger
Browse files

Merge "Use precompiled sepolicy when available"

am: dda9cbb3

Change-Id: I801189104c263b21d2252d957af25149cfbef648
parents 0d9416ba dda9cbb3
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