aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2018-11-29 16:50:37 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-11-29 16:50:37 +0000
commitc7cbef4f2dca7de4fb6186df05e0208d7d7fbfa5 (patch)
tree2e007e9e9dbc3ae5d85059bb51c9b15acf408c91
parent7260329093c3a36536e0bebf4ed5b929430f4efb (diff)
parent66bc428f93546065ca73779ebefd1082244ecea2 (diff)
downloadbionic-nougat-iot-release.tar.gz
Merge "linker: changes to init work arounds"android-n-iot-release-ihome-igv1nougat-iot-release
-rw-r--r--linker/linker.cpp34
-rw-r--r--linker/linker_main.cpp16
-rw-r--r--linker/linker_phdr.cpp4
-rw-r--r--linker/linker_soinfo.cpp2
-rw-r--r--linker/linker_utils.cpp4
-rw-r--r--linker/linker_utils.h2
6 files changed, 42 insertions, 20 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 7993681d3..b437f0688 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -354,7 +354,9 @@ static bool realpath_fd(int fd, std::string* realpath) {
std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
async_safe_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
- PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
+ if (!is_first_stage_init()) {
+ PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
+ }
return false;
}
@@ -993,8 +995,10 @@ static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache,
if (realpath_fd(fd, realpath)) {
*realpath += separator;
} else {
- PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
- normalized_path.c_str());
+ if (!is_first_stage_init()) {
+ PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
+ normalized_path.c_str());
+ }
*realpath = normalized_path;
}
@@ -1024,7 +1028,10 @@ static int open_library_at_path(ZipArchiveCache* zip_archive_cache,
if (fd != -1) {
*file_offset = 0;
if (!realpath_fd(fd, realpath)) {
- PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", path);
+ if (!is_first_stage_init()) {
+ PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
+ path);
+ }
*realpath = path;
}
}
@@ -1071,7 +1078,10 @@ static int open_library(android_namespace_t* ns,
if (fd != -1) {
*file_offset = 0;
if (!realpath_fd(fd, realpath)) {
- PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", name);
+ if (!is_first_stage_init()) {
+ PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
+ name);
+ }
*realpath = name;
}
}
@@ -1354,8 +1364,12 @@ static bool load_library(android_namespace_t* ns,
}
if (!realpath_fd(extinfo->library_fd, &realpath)) {
- PRINT("warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
- "Will use given name.", name);
+ if (!is_first_stage_init()) {
+ PRINT(
+ "warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
+ "Will use given name.",
+ name);
+ }
realpath = name;
}
@@ -1510,9 +1524,9 @@ static bool find_library_internal(android_namespace_t* ns,
static void soinfo_unload(soinfo* si);
static void shuffle(std::vector<LoadTask*>* v) {
- if (is_init()) {
- // arc4random* is not available in init because /dev/random hasn't yet been
- // created.
+ if (is_first_stage_init()) {
+ // arc4random* is not available in first stage init because /dev/random
+ // hasn't yet been created.
return;
}
for (size_t i = 0, size = v->size(); i < size; ++i) {
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 66766fe56..82b10b74b 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -195,11 +195,19 @@ struct ExecutableInfo {
static ExecutableInfo get_executable_info(KernelArgumentBlock& args) {
ExecutableInfo result = {};
- if (is_init()) {
- // /proc fs is not mounted when init starts. Therefore we can't use
- // /proc/self/exe for init.
+ if (is_first_stage_init()) {
+ // /proc fs is not mounted when first stage init starts. Therefore we can't
+ // use /proc/self/exe for init.
stat("/init", &result.file_stat);
- result.path = "/init";
+
+ // /init may be a symlink, so try to read it as such.
+ char path[PATH_MAX];
+ ssize_t path_len = readlink("/init", path, sizeof(path));
+ if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
+ result.path = "/init";
+ } else {
+ result.path = std::string(path, path_len);
+ }
} else {
// Stat "/proc/self/exe" instead of executable_path because
// the executable could be unlinked by this point and it should
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 0123d3c7b..34ac60668 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -547,9 +547,9 @@ static void* ReserveAligned(size_t size, size_t align) {
uint8_t* first = align_up(mmap_ptr, align);
uint8_t* last = align_down(mmap_ptr + mmap_size, align) - size;
- // arc4random* is not available in init because /dev/urandom hasn't yet been
+ // arc4random* is not available in first stage init because /dev/urandom hasn't yet been
// created. Don't randomize then.
- size_t n = is_init() ? 0 : arc4random_uniform((last - first) / PAGE_SIZE + 1);
+ size_t n = is_first_stage_init() ? 0 : arc4random_uniform((last - first) / PAGE_SIZE + 1);
uint8_t* start = first + n * PAGE_SIZE;
munmap(mmap_ptr, start - mmap_ptr);
munmap(start + size, mmap_ptr + mmap_size - (start + size));
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index 71e8a4dab..93079cae6 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -748,7 +748,7 @@ void soinfo::generate_handle() {
// Make sure the handle is unique and does not collide
// with special values which are RTLD_DEFAULT and RTLD_NEXT.
do {
- if (!is_init()) {
+ if (!is_first_stage_init()) {
arc4random_buf(&handle_, sizeof(handle_));
} else {
// arc4random* is not available in init because /dev/urandom hasn't yet been
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index d08b161ca..e92667157 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -247,7 +247,7 @@ void resolve_paths(std::vector<std::string>& paths,
}
}
-bool is_init() {
- static bool ret = (getpid() == 1);
+bool is_first_stage_init() {
+ static bool ret = (getpid() == 1 && access("/proc/self/exe", F_OK) == -1);
return ret;
}
diff --git a/linker/linker_utils.h b/linker/linker_utils.h
index b15082d95..34a597b98 100644
--- a/linker/linker_utils.h
+++ b/linker/linker_utils.h
@@ -55,4 +55,4 @@ std::string dirname(const char* path);
off64_t page_start(off64_t offset);
size_t page_offset(off64_t offset);
bool safe_add(off64_t* out, off64_t a, size_t b);
-bool is_init();
+bool is_first_stage_init();