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

Commit 80416f7a authored by Kiyoung Kim's avatar Kiyoung Kim Committed by Gerrit Code Review
Browse files

Merge "Generate linkerconfig per mount namespaces"

parents e8537ccf e4d3f212
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
#include <fs_mgr.h>
#include <fscrypt/fscrypt.h>
#include <libgsi/libgsi.h>
#include <logwrap/logwrap.h>
#include <selinux/android.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
@@ -1176,6 +1177,42 @@ static Result<void> do_mark_post_data(const BuiltinArguments& args) {
    return {};
}

static Result<void> GenerateLinkerConfiguration() {
    const char* linkerconfig_binary = "/system/bin/linkerconfig";
    const char* linkerconfig_target = "/linkerconfig/ld.config.txt";
    const char* arguments[] = {linkerconfig_binary, "--target", linkerconfig_target};

    if (logwrap_fork_execvp(arraysize(arguments), arguments, nullptr, false, LOG_KLOG, false,
                            nullptr) != 0) {
        return ErrnoError() << "failed to execute linkerconfig";
    }

    mode_t mode = get_mode("0444");
    if (fchmodat(AT_FDCWD, linkerconfig_target, mode, AT_SYMLINK_NOFOLLOW) < 0) {
        return ErrnoErrorIgnoreEnoent() << "fchmodat() failed";
    }

    LOG(INFO) << "linkerconfig generated " << linkerconfig_target
              << " with mounted APEX modules info";

    return {};
}

static bool IsApexUpdatable() {
    static bool updatable = android::sysprop::ApexProperties::updatable().value_or(false);
    return updatable;
}

static Result<void> do_update_linker_config(const BuiltinArguments&) {
    // If APEX is not updatable, then all APEX information are already included in the first
    // linker config generation, so there is no need to update linker configuration again.
    if (IsApexUpdatable()) {
        return GenerateLinkerConfiguration();
    }

    return {};
}

static Result<void> parse_apex_configs() {
    glob_t glob_result;
    static constexpr char glob_pattern[] = "/apex/*/etc/*.rc";
@@ -1251,6 +1288,12 @@ static Result<void> do_perform_apex_config(const BuiltinArguments& args) {
    if (!parse_configs) {
        return parse_configs.error();
    }

    auto update_linker_config = do_update_linker_config(args);
    if (!update_linker_config) {
        return update_linker_config.error();
    }

    return {};
}

@@ -1317,6 +1360,7 @@ const BuiltinFunctionMap& GetBuiltinFunctionMap() {
        {"perform_apex_config",     {0,     0,    {false,  do_perform_apex_config}}},
        {"umount",                  {1,     1,    {false,  do_umount}}},
        {"umount_all",              {1,     1,    {false,  do_umount_all}}},
        {"update_linker_config",    {0,     0,    {false,  do_update_linker_config}}},
        {"readahead",               {1,     2,    {true,   do_readahead}}},
        {"remount_userdata",        {0,     0,    {false,  do_remount_userdata}}},
        {"restart",                 {1,     1,    {false,  do_restart}}},
+19 −0
Original line number Diff line number Diff line
@@ -151,6 +151,20 @@ static bool ActivateFlattenedApexesIfPossible() {
    return true;
}

static Result<void> MountLinkerConfigForDefaultNamespace() {
    // No need to mount linkerconfig for default mount namespace if the path does not exist (which
    // would mean it is already mounted)
    if (access("/linkerconfig/default", 0) != 0) {
        return {};
    }

    if (mount("/linkerconfig/default", "/linkerconfig", nullptr, MS_BIND | MS_REC, nullptr) != 0) {
        return ErrnoError() << "Failed to mount linker configuration for default mount namespace.";
    }

    return {};
}

static android::base::unique_fd bootstrap_ns_fd;
static android::base::unique_fd default_ns_fd;

@@ -222,6 +236,11 @@ bool SwitchToDefaultMountNamespace() {
            PLOG(ERROR) << "Failed to switch back to the default mount namespace.";
            return false;
        }

        if (auto result = MountLinkerConfigForDefaultNamespace(); !result) {
            LOG(ERROR) << result.error();
            return false;
        }
    }

    LOG(INFO) << "Switched to default mount namespace";
+14 −2
Original line number Diff line number Diff line
@@ -38,9 +38,18 @@ on early-init
    # Allow up to 32K FDs per process
    setrlimit nofile 32768 32768

    # Set up linker config subdirectories based on mount namespaces
    mkdir /linkerconfig/bootstrap 0755
    mkdir /linkerconfig/default 0755

    # Generate ld.config.txt for early executed processes
    exec -- /system/bin/linkerconfig --target /linkerconfig/ld.config.txt
    chmod 444 /linkerconfig/ld.config.txt
    exec -- /system/bin/linkerconfig --target /linkerconfig/bootstrap/ld.config.txt
    chmod 644 /linkerconfig/bootstrap/ld.config.txt
    copy /linkerconfig/bootstrap/ld.config.txt /linkerconfig/default/ld.config.txt
    chmod 644 /linkerconfig/default/ld.config.txt

    # Mount bootstrap linker configuration as current
    mount none /linkerconfig/bootstrap /linkerconfig bind rec

    start ueventd

@@ -49,6 +58,9 @@ on early-init
    # the libraries are available to the processes started after this statement.
    exec_start apexd-bootstrap

    # Generate linker config based on apex mounted in bootstrap namespace
    update_linker_config

    # These must already exist by the time boringssl_self_test32 / boringssl_self_test64 run.
    mkdir /dev/boringssl 0755 root root
    mkdir /dev/boringssl/selftest 0755 root root