summaryrefslogtreecommitdiff
path: root/linker/linker_main.cpp
diff options
context:
space:
mode:
authorJiyong Park <jiyong@google.com>2018-06-01 19:18:56 +0900
committerJiyong Park <jiyong@google.com>2018-06-08 14:50:14 +0900
commit31cd08f9eb857963ce1ab331d0ecf0c6c6b79670 (patch)
tree38fb9f800a8976a03b047c54e8b138f272f60eec /linker/linker_main.cpp
parent8d7866c58f95695e65e8780712cc6c692fb4af72 (diff)
dynamic linker is running for init
init is now built as a dynamic executable, so the dynamic linker has to be able to run in the init process. However, since init is launched so early, even /dev/* and /proc/* file systems are not mounted and thus some APIs that rely on the paths do not work. The dynamic linker now goes alternative path when it is running in the init process. For example, /proc/self/exe is not read for the init since we always now the path of the init (/init). Also, arc4random* APIs are not used since the APIs rely on /dev/urandom. Linker now does not randomize library loading order and addresses when running in the init process. Bug: 80454183 Test: `adb reboot recovery; adb devices` shows the device ID Change-Id: I29b6d70e4df5f7f690876126d5fe81258c1d3115
Diffstat (limited to 'linker/linker_main.cpp')
-rw-r--r--linker/linker_main.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 1a0d1642b..a8741527e 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -197,12 +197,16 @@ extern "C" int __system_properties_init(void);
static const char* get_executable_path() {
static std::string executable_path;
if (executable_path.empty()) {
- char path[PATH_MAX];
- ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
- if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
- async_safe_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
+ if (!is_init()) {
+ char path[PATH_MAX];
+ ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
+ if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
+ async_safe_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
+ }
+ executable_path = std::string(path, path_len);
+ } else {
+ executable_path = "/init";
}
- executable_path = std::string(path, path_len);
}
return executable_path.c_str();
@@ -288,8 +292,14 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args) {
// Stat "/proc/self/exe" instead of executable_path because
// the executable could be unlinked by this point and it should
// not cause a crash (see http://b/31084669)
- if (TEMP_FAILURE_RETRY(stat("/proc/self/exe", &file_stat)) != 0) {
- async_safe_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno));
+ if (!is_init()) {
+ if (TEMP_FAILURE_RETRY(stat("/proc/self/exe", &file_stat)) != 0) {
+ async_safe_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno));
+ }
+ } else {
+ // /proc fs is not mounted when init starts. Therefore we can't use
+ // /proc/self/exe for init.
+ stat("/init", &file_stat);
}
const char* executable_path = get_executable_path();