Generate linkerconfig per mount namespaces
There are two namespaces from init - bootstrap and default - and those will have different set of APEX modules. To support difference between two namespaces, linker config should be generated per namespace and each namespace should use its own linker configuration. As a first step of the work, this change will create different mount point for each namespace, and re-generate linker config after APEX mount from each namespaces. Bug: 144664390 Test: m -j passed & tested from cuttlefish Change-Id: Iac2e222376ec4b0ced6c29eed18b21d39ff0b1ba
This commit is contained in:
parent
1cdcc5f7e8
commit
e4d3f2123f
3 changed files with 77 additions and 2 deletions
|
@ -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}}},
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue