diff options
author | Tom Cherry <tomcherry@google.com> | 2018-11-29 16:50:37 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-11-29 16:50:37 +0000 |
commit | c7cbef4f2dca7de4fb6186df05e0208d7d7fbfa5 (patch) | |
tree | 2e007e9e9dbc3ae5d85059bb51c9b15acf408c91 | |
parent | 7260329093c3a36536e0bebf4ed5b929430f4efb (diff) | |
parent | 66bc428f93546065ca73779ebefd1082244ecea2 (diff) | |
download | bionic-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.cpp | 34 | ||||
-rw-r--r-- | linker/linker_main.cpp | 16 | ||||
-rw-r--r-- | linker/linker_phdr.cpp | 4 | ||||
-rw-r--r-- | linker/linker_soinfo.cpp | 2 | ||||
-rw-r--r-- | linker/linker_utils.cpp | 4 | ||||
-rw-r--r-- | linker/linker_utils.h | 2 |
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(); |