Merge "Fix potential race condition on CTS TC pthread_gettid_np" into marshmallow-cts-dev am: 2010fb6722
am: eebe01b523

* commit 'eebe01b523075c0634b04463c210510f192f154d':
  Fix potential race condition on CTS TC pthread_gettid_np
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 3b91e6a..6a39a21 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -130,8 +130,13 @@
  */
 #define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ)
 
-/* Leave room for a guard page in the internally created signal stacks. */
+// Leave room for a guard page in the internally created signal stacks.
+#if defined(__LP64__)
+// SIGSTKSZ is not big enough for 64-bit arch. See http://b/23041777.
+#define SIGNAL_STACK_SIZE (16 * 1024 + PAGE_SIZE)
+#else
 #define SIGNAL_STACK_SIZE (SIGSTKSZ + PAGE_SIZE)
+#endif
 
 /* Needed by fork. */
 __LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index f22464e..c464f46 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b860f70..d3ac1d0 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -37,6 +37,7 @@
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/param.h>
+#include <sys/prctl.h>
 #include <unistd.h>
 
 #include <new>
@@ -317,6 +318,13 @@
 static bool realpath_fd(int fd, std::string* realpath) {
   std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
   snprintf(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
+  // set DUMPABLE to 1 to access /proc/self/fd
+  int dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+  auto guard = make_scope_guard([&]() {
+    // restore dumpable
+    prctl(PR_SET_DUMPABLE, dumpable, 0, 0, 0);
+  });
   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);
     return false;
@@ -1468,13 +1476,14 @@
   // Step 1: load and pre-link all DT_NEEDED libraries in breadth first order.
   for (LoadTask::unique_ptr task(load_tasks.pop_front());
       task.get() != nullptr; task.reset(load_tasks.pop_front())) {
-    soinfo* si = find_library_internal(load_tasks, task->get_name(), rtld_flags, extinfo);
+    soinfo* needed_by = task->get_needed_by();
+
+    soinfo* si = find_library_internal(load_tasks, task->get_name(),
+                                       rtld_flags, needed_by == nullptr ? extinfo : nullptr);
     if (si == nullptr) {
       return false;
     }
 
-    soinfo* needed_by = task->get_needed_by();
-
     if (needed_by != nullptr) {
       needed_by->add_child(si);
     }
@@ -2936,6 +2945,7 @@
     // TODO (dimitry): remove != __ANDROID_API__ check once http://b/20020312 is fixed
     if (get_application_target_sdk_version() != __ANDROID_API__
         && get_application_target_sdk_version() > 22) {
+      PRINT("%s: has text relocations", get_realpath());
       DL_ERR("%s: has text relocations", get_realpath());
       return false;
     }
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index a5ef622..5b96306 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -67,6 +67,8 @@
 libdlext_test_ldflags := \
     -Wl,-z,relro \
 
+libdlext_test_shared_libraries := libtest_simple
+
 module := libdlext_test
 module_tag := optional
 include $(LOCAL_PATH)/Android.build.testlib.mk
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index f15cdab..e210255 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -27,6 +27,7 @@
 #include <sys/syscall.h>
 #include <time.h>
 #include <unistd.h>
+#include <unwind.h>
 
 #include <atomic>
 #include <regex>
@@ -1578,3 +1579,26 @@
   GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
 #endif
 }
+
+extern _Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx, void* arg);
+
+static volatile bool signal_handler_on_altstack_done;
+
+static void SignalHandlerOnAltStack(int signo, siginfo_t*, void*) {
+  ASSERT_EQ(SIGUSR1, signo);
+  // Check if we have enough stack space for unwinding.
+  int count = 0;
+  _Unwind_Backtrace(FrameCounter, &count);
+  ASSERT_GT(count, 0);
+  // Check if we have enough stack space for logging.
+  std::string s(2048, '*');
+  GTEST_LOG_(INFO) << s;
+  signal_handler_on_altstack_done = true;
+}
+
+TEST(pthread, big_enough_signal_stack_for_64bit_arch) {
+  signal_handler_on_altstack_done = false;
+  ScopedSignalHandler handler(SIGUSR1, SignalHandlerOnAltStack, SA_SIGINFO | SA_ONSTACK);
+  kill(getpid(), SIGUSR1);
+  ASSERT_TRUE(signal_handler_on_altstack_done);
+}
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index d1b3402..afd9e7f 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -34,7 +34,7 @@
 #define noinline __attribute__((__noinline__))
 #define __unused __attribute__((__unused__))
 
-static _Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) {
+_Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) {
   int* count_ptr = reinterpret_cast<int*>(arg);
 
 #if SHOW_FRAME_LOCATIONS