Merge "Generate linkerconfig per mount namespaces"

This commit is contained in:
Kiyoung Kim 2019-12-20 03:30:33 +00:00 committed by Gerrit Code Review
commit 80416f7a80
3 changed files with 77 additions and 2 deletions

View file

@ -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}}},

View file

@ -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";

View file

@ -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