Merge "Replace #apex with #systemapi"
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 4bbbc20..ff95487 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -507,16 +507,22 @@
SaveRamdiskPathToSnapuserd();
}
- if (MountPartition(system_partition, false /* erase_same_mounts */)) {
- if (dsu_not_on_userdata_ && fs_mgr_verity_is_check_at_most_once(*system_partition)) {
- LOG(ERROR) << "check_most_at_once forbidden on external media";
- return false;
- }
- SwitchRoot("/system");
- } else {
+ if (!MountPartition(system_partition, false /* erase_same_mounts */)) {
PLOG(ERROR) << "Failed to mount /system";
return false;
}
+ if (dsu_not_on_userdata_ && fs_mgr_verity_is_check_at_most_once(*system_partition)) {
+ LOG(ERROR) << "check_at_most_once forbidden on external media";
+ return false;
+ }
+
+ SwitchRoot("/system");
+
+ // Make /system a mountpoint so that adb-remount can move submounts under /system.
+ if (access("/system", F_OK) == 0 &&
+ mount("/system", "/system", nullptr, MS_BIND, nullptr) != 0) {
+ PLOG(WARNING) << "Failed to bind mount /system for overlayfs";
+ }
return true;
}
diff --git a/init/init.cpp b/init/init.cpp
index 0658942..535033d 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -54,6 +54,7 @@
#include <libavb/libavb.h>
#include <libgsi/libgsi.h>
#include <libsnapshot/snapshot.h>
+#include <logwrap/logwrap.h>
#include <processgroup/processgroup.h>
#include <processgroup/setup.h>
#include <selinux/android.h>
@@ -442,17 +443,43 @@
return {};
}
-static void DoUnloadApex(const std::string& apex_name) {
+static Result<void> DoUnloadApex(const std::string& apex_name) {
std::string prop_name = "init.apex." + apex_name;
// TODO(b/232114573) remove services and actions read from the apex
// TODO(b/232799709) kill services from the apex
SetProperty(prop_name, "unloaded");
+ return {};
}
-static void DoLoadApex(const std::string& apex_name) {
+static Result<void> UpdateApexLinkerConfig(const std::string& apex_name) {
+ // Do not invoke linkerconfig when there's no bin/ in the apex.
+ const std::string bin_path = "/apex/" + apex_name + "/bin";
+ if (access(bin_path.c_str(), R_OK) != 0) {
+ return {};
+ }
+ const char* linkerconfig_binary = "/apex/com.android.runtime/bin/linkerconfig";
+ const char* linkerconfig_target = "/linkerconfig";
+ const char* arguments[] = {linkerconfig_binary, "--target", linkerconfig_target, "--apex",
+ apex_name.c_str(), "--strict"};
+
+ if (logwrap_fork_execvp(arraysize(arguments), arguments, nullptr, false, LOG_KLOG, false,
+ nullptr) != 0) {
+ return ErrnoError() << "failed to execute linkerconfig";
+ }
+ LOG(INFO) << "Generated linker configuration for " << apex_name;
+ return {};
+}
+
+static Result<void> DoLoadApex(const std::string& apex_name) {
std::string prop_name = "init.apex." + apex_name;
// TODO(b/232799709) read .rc files from the apex
+
+ if (auto result = UpdateApexLinkerConfig(apex_name); !result.ok()) {
+ return result.error();
+ }
+
SetProperty(prop_name, "loaded");
+ return {};
}
enum class ControlTarget {
@@ -478,17 +505,14 @@
return control_message_functions;
}
-static bool HandleApexControlMessage(std::string_view action, const std::string& name,
- std::string_view message) {
+static Result<void> HandleApexControlMessage(std::string_view action, const std::string& name,
+ std::string_view message) {
if (action == "load") {
- DoLoadApex(name);
- return true;
+ return DoLoadApex(name);
} else if (action == "unload") {
- DoUnloadApex(name);
- return true;
+ return DoUnloadApex(name);
} else {
- LOG(ERROR) << "Unknown control msg '" << message << "'";
- return false;
+ return Error() << "Unknown control msg '" << message << "'";
}
}
@@ -505,7 +529,15 @@
auto action = message;
if (ConsumePrefix(&action, "apex_")) {
- return HandleApexControlMessage(action, name, message);
+ if (auto result = HandleApexControlMessage(action, name, message); !result.ok()) {
+ LOG(ERROR) << "Control message: Could not ctl." << message << " for '" << name
+ << "' from pid: " << from_pid << " (" << process_cmdline
+ << "): " << result.error();
+ return false;
+ }
+ LOG(INFO) << "Control message: Processed ctl." << message << " for '" << name
+ << "' from pid: " << from_pid << " (" << process_cmdline << ")";
+ return true;
}
Service* service = nullptr;
diff --git a/init/security.cpp b/init/security.cpp
index 970696e..0e9f6c2 100644
--- a/init/security.cpp
+++ b/init/security.cpp
@@ -15,6 +15,7 @@
*/
#include "security.h"
+#include "util.h"
#include <errno.h>
#include <fcntl.h>
@@ -89,7 +90,7 @@
// Set /proc/sys/vm/mmap_rnd_bits and potentially
// /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
-// Returns -1 if unable to set these to an acceptable value.
+// Returns an error if unable to set these to an acceptable value.
//
// To support this sysctl, the following upstream commits are needed:
//
@@ -105,13 +106,20 @@
// uml does not support mmap_rnd_bits
return {};
#elif defined(__aarch64__)
- // arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE
- if (SetMmapRndBitsMin(33, 24, false) && SetMmapRndBitsMin(16, 16, true)) {
+ // arm64 architecture supports 18 - 33 rnd bits depending on pagesize and
+ // VA_SIZE. However the kernel might have been compiled with a narrower
+ // range using CONFIG_ARCH_MMAP_RND_BITS_MIN/MAX. To use the maximum
+ // supported number of bits, we start from the theoretical maximum of 33
+ // bits and try smaller values until we reach 24 bits which is the
+ // Android-specific minimum. Don't go lower even if the configured maximum
+ // is smaller than 24.
+ if (SetMmapRndBitsMin(33, 24, false) && (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
return {};
}
#elif defined(__x86_64__)
- // x86_64 supports 28 - 32 bits
- if (SetMmapRndBitsMin(32, 32, false) && SetMmapRndBitsMin(16, 16, true)) {
+ // x86_64 supports 28 - 32 rnd bits, but Android wants to ensure that the
+ // theoretical maximum of 32 bits is always supported and used.
+ if (SetMmapRndBitsMin(32, 32, false) && (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
return {};
}
#elif defined(__arm__) || defined(__i386__)
diff --git a/init/util.cpp b/init/util.cpp
index 1801d17..523cce4 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -733,5 +733,10 @@
return is_microdroid;
}
+bool Has32BitAbi() {
+ static bool has = !android::base::GetProperty("ro.product.cpu.abilist32", "").empty();
+ return has;
+}
+
} // namespace init
} // namespace android
diff --git a/init/util.h b/init/util.h
index 47d4ff5..099b9ee 100644
--- a/init/util.h
+++ b/init/util.h
@@ -106,5 +106,6 @@
void SetDefaultMountNamespaceReady();
bool IsMicrodroid();
+bool Has32BitAbi();
} // namespace init
} // namespace android