Merge changes from topic "sharedlib_in_recovery" am: 2583b0adb2
am: bbf6d709d4
Change-Id: Ia4f7085b1e9da70668655516501759ca68893877
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 9503a49..9094b0a 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1489,6 +1489,11 @@
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.
+ return;
+ }
for (size_t i = 0, size = v->size(); i < size; ++i) {
size_t n = size - i;
size_t r = arc4random_uniform(n);
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 1a0d164..a874152 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -197,12 +197,16 @@
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 @@
// 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();
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index a5eab44..b24be92 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -547,7 +547,10 @@
uint8_t* first = align_up(mmap_ptr, align);
uint8_t* last = align_down(mmap_ptr + mmap_size, align) - size;
- size_t n = arc4random_uniform((last - first) / PAGE_SIZE + 1);
+
+ // arc4random* is not available in 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);
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 3191ac7..795b01d 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -748,7 +748,14 @@
// Make sure the handle is unique and does not collide
// with special values which are RTLD_DEFAULT and RTLD_NEXT.
do {
- arc4random_buf(&handle_, sizeof(handle_));
+ if (!is_init()) {
+ arc4random_buf(&handle_, sizeof(handle_));
+ } else {
+ // arc4random* is not available in init because /dev/urandom hasn't yet been
+ // created. So, when running with init, use the monotonically increasing
+ // numbers as handles
+ handle_ += 2;
+ }
// the least significant bit for the handle is always 1
// making it easy to test the type of handle passed to
// dl* functions.
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index 661e7cb..789d5c1 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -239,3 +239,8 @@
}
}
}
+
+bool is_init() {
+ static bool ret = (getpid() == 1);
+ return ret;
+}
diff --git a/linker/linker_utils.h b/linker/linker_utils.h
index 214646c..b15082d 100644
--- a/linker/linker_utils.h
+++ b/linker/linker_utils.h
@@ -55,3 +55,4 @@
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();