Merge "Don't print 168^W143 lines of help when someone makes a typo."
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 58eaed7..4e083ae 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -18,10 +18,12 @@
 #include <dirent.h>
 #include <fcntl.h>
 #include <stdlib.h>
-#include <syscall.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
 #include <sys/ptrace.h>
 #include <sys/types.h>
 #include <sys/un.h>
+#include <syscall.h>
 #include <unistd.h>
 
 #include <limits>
@@ -51,24 +53,25 @@
 using android::base::unique_fd;
 using android::base::StringPrintf;
 
-static bool pid_contains_tid(pid_t pid, pid_t tid) {
-  std::string task_path = StringPrintf("/proc/%d/task/%d", pid, tid);
-  return access(task_path.c_str(), F_OK) == 0;
+static bool pid_contains_tid(int pid_proc_fd, pid_t tid) {
+  struct stat st;
+  std::string task_path = StringPrintf("task/%d", tid);
+  return fstatat(pid_proc_fd, task_path.c_str(), &st, 0) == 0;
 }
 
 // Attach to a thread, and verify that it's still a member of the given process
-static bool ptrace_seize_thread(pid_t pid, pid_t tid, std::string* error) {
+static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error) {
   if (ptrace(PTRACE_SEIZE, tid, 0, 0) != 0) {
     *error = StringPrintf("failed to attach to thread %d: %s", tid, strerror(errno));
     return false;
   }
 
   // Make sure that the task we attached to is actually part of the pid we're dumping.
-  if (!pid_contains_tid(pid, tid)) {
+  if (!pid_contains_tid(pid_proc_fd, tid)) {
     if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
       PLOG(FATAL) << "failed to detach from thread " << tid;
     }
-    *error = StringPrintf("thread %d is not in process %d", tid, pid);
+    *error = StringPrintf("thread %d is not in process", tid);
     return false;
   }
 
@@ -190,6 +193,24 @@
   _exit(1);
 }
 
+static void drop_capabilities() {
+  __user_cap_header_struct capheader;
+  memset(&capheader, 0, sizeof(capheader));
+  capheader.version = _LINUX_CAPABILITY_VERSION_3;
+  capheader.pid = 0;
+
+  __user_cap_data_struct capdata[2];
+  memset(&capdata, 0, sizeof(capdata));
+
+  if (capset(&capheader, &capdata[0]) == -1) {
+    PLOG(FATAL) << "failed to drop capabilities";
+  }
+
+  if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) {
+    PLOG(FATAL) << "failed to set PR_SET_NO_NEW_PRIVS";
+  }
+}
+
 static void check_process(int proc_fd, pid_t expected_pid) {
   android::procinfo::ProcessInfo proc_info;
   if (!android::procinfo::GetProcessInfoFromProcPidFd(proc_fd, &proc_info)) {
@@ -263,7 +284,7 @@
   check_process(target_proc_fd, target);
 
   std::string attach_error;
-  if (!ptrace_seize_thread(target, main_tid, &attach_error)) {
+  if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
     LOG(FATAL) << attach_error;
   }
 
@@ -304,6 +325,7 @@
   }
 
   int signo = siginfo.si_signo;
+  bool fatal_signal = signo != DEBUGGER_SIGNAL;
   bool backtrace = false;
   uintptr_t abort_address = 0;
 
@@ -319,17 +341,16 @@
 
   // Now that we have the signal that kicked things off, attach all of the
   // sibling threads, and then proceed.
-  bool fatal_signal = signo != DEBUGGER_SIGNAL;
-  std::set<pid_t> siblings;
   std::set<pid_t> attached_siblings;
-  if (fatal_signal || backtrace) {
+  {
+    std::set<pid_t> siblings;
     if (!android::procinfo::GetProcessTids(target, &siblings)) {
       PLOG(FATAL) << "failed to get process siblings";
     }
     siblings.erase(main_tid);
 
     for (pid_t sibling_tid : siblings) {
-      if (!ptrace_seize_thread(target, sibling_tid, &attach_error)) {
+      if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
         LOG(WARNING) << attach_error;
       } else {
         attached_siblings.insert(sibling_tid);
@@ -337,11 +358,18 @@
     }
   }
 
+  std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid));
+  if (!backtrace_map) {
+    LOG(FATAL) << "failed to create backtrace map";
+  }
+
+  // Drop our capabilities now that we've attached to the threads we care about.
+  drop_capabilities();
+
   check_process(target_proc_fd, target);
 
   // TODO: Use seccomp to lock ourselves down.
 
-  std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid));
   std::string amfd_data;
 
   if (backtrace) {
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index 9469bbd..38a7be3 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -39,6 +39,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/capability.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
 #include <sys/socket.h>
@@ -207,7 +208,7 @@
   }
 
   // Don't use fork(2) to avoid calling pthread_atfork handlers.
-  int forkpid = clone(nullptr, nullptr, SIGCHLD, nullptr);
+  int forkpid = clone(nullptr, nullptr, 0, nullptr);
   if (forkpid == -1) {
     __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to fork in debuggerd signal handler: %s",
                       strerror(errno));
@@ -216,6 +217,11 @@
     close(pipefds[0]);
     close(pipefds[1]);
 
+    // Set all of the ambient capability bits we can, so that crash_dump can ptrace us.
+    for (unsigned long i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) != -1; ++i) {
+      prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0);
+    }
+
     char buf[10];
     snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid);
     execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr);
@@ -242,10 +248,12 @@
     close(pipefds[0]);
 
     // Don't leave a zombie child.
-    siginfo_t child_siginfo;
-    if (TEMP_FAILURE_RETRY(waitid(P_PID, forkpid, &child_siginfo, WEXITED)) != 0) {
+    int status;
+    if (TEMP_FAILURE_RETRY(waitpid(forkpid, &status, __WCLONE)) == -1 && errno != ECHILD) {
       __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
                         strerror(errno));
+    } else if (WIFSTOPPED(status) || WIFSIGNALED(status)) {
+      __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper crashed or stopped");
       thread_info->crash_dump_started = false;
     }
   }
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 965a81f..2388edc 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -265,10 +265,14 @@
     if (!svc) {
         return -1;
     }
-    if (!svc->Start()) {
+    if (!start_waiting_for_exec()) {
         return -1;
     }
-    waiting_for_exec = true;
+    if (!svc->Start()) {
+        stop_waiting_for_exec();
+        ServiceManager::GetInstance().RemoveService(*svc);
+        return -1;
+    }
     return 0;
 }
 
@@ -1018,7 +1022,7 @@
                    << "\") failed: value too long";
         return -1;
     }
-    if (!wait_property(name, value)) {
+    if (!start_waiting_for_property(name, value)) {
         LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value
                    << "\") failed: init already in waiting";
         return -1;
diff --git a/init/init.cpp b/init/init.cpp
index c8c18d2..43f601f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -82,7 +82,7 @@
 
 const char *ENV[32];
 
-bool waiting_for_exec = false;
+static std::unique_ptr<Timer> waiting_for_exec(nullptr);
 
 static int epoll_fd = -1;
 
@@ -131,7 +131,24 @@
     return -1;
 }
 
-bool wait_property(const char *name, const char *value)
+bool start_waiting_for_exec()
+{
+    if (waiting_for_exec) {
+        return false;
+    }
+    waiting_for_exec.reset(new Timer());
+    return true;
+}
+
+void stop_waiting_for_exec()
+{
+    if (waiting_for_exec) {
+        LOG(INFO) << "Wait for exec took " << *waiting_for_exec;
+        waiting_for_exec.reset();
+    }
+}
+
+bool start_waiting_for_property(const char *name, const char *value)
 {
     if (waiting_for_prop) {
         return false;
@@ -142,7 +159,8 @@
         wait_prop_value = value;
         waiting_for_prop.reset(new Timer());
     } else {
-        LOG(INFO) << "wait_property(\"" << name << "\", \"" << value << "\"): already set";
+        LOG(INFO) << "start_waiting_for_property(\""
+                  << name << "\", \"" << value << "\"): already set";
     }
     return true;
 }
diff --git a/init/init.h b/init/init.h
index 4e4da32..3768c02 100644
--- a/init/init.h
+++ b/init/init.h
@@ -23,7 +23,6 @@
 class Service;
 
 extern const char *ENV[32];
-extern bool waiting_for_exec;
 extern std::string default_console;
 extern struct selabel_handle *sehandle;
 extern struct selabel_handle *sehandle_prop;
@@ -36,6 +35,10 @@
 
 int add_environment(const char* key, const char* val);
 
-bool wait_property(const char *name, const char *value);
+bool start_waiting_for_exec();
+
+void stop_waiting_for_exec();
+
+bool start_waiting_for_property(const char *name, const char *value);
 
 #endif  /* _INIT_INIT_H */
diff --git a/init/service.cpp b/init/service.cpp
index 0f7f62f..e186f27 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -997,7 +997,7 @@
     }
 
     if (svc->Reap()) {
-        waiting_for_exec = false;
+        stop_waiting_for_exec();
         RemoveService(*svc);
     }
 
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 013999a..b701bba 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -177,11 +177,8 @@
                                            CAP_MASK_LONG(CAP_SETPCAP),
                                               "system/bin/webview_zygote64" },
 
-    { 00755, AID_ROOT,      AID_SHELL,     CAP_MASK_LONG(CAP_SYS_PTRACE),
-                                              "system/bin/crash_dump32" },
-    { 00755, AID_ROOT,      AID_SHELL,     CAP_MASK_LONG(CAP_SYS_PTRACE),
-                                              "system/bin/crash_dump64" },
-
+    { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/crash_dump32" },
+    { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/crash_dump64" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/debuggerd" },
     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/uncrypt" },
     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/install-recovery.sh" },
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index 1a2d506..4324125 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -514,6 +514,14 @@
             strcpy(buf, "Unspecified assertion failed");
     }
 
+    // Log assertion failures to stderr for the benefit of "adb shell" users
+    // and gtests (http://b/23675822).
+    struct iovec iov[2] = {
+        { buf, strlen(buf) },
+        { (char*) "\n", 1 },
+    };
+    TEMP_FAILURE_RETRY(writev(2, iov, 2));
+
     __android_log_write(ANDROID_LOG_FATAL, tag, buf);
     abort(); /* abort so we have a chance to debug the situation */
     /* NOTREACHED */
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index d7b5cb5..2f23c2c 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -246,7 +246,9 @@
     // For now we rely on CTS test to catch things like this but
     // it should probably be addressed in the future.
     for (const auto& soname : sonames) {
-      dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE);
+      LOG_ALWAYS_FATAL_IF(dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE) == nullptr,
+                          "Error preloading public library %s: %s",
+                          soname.c_str(), dlerror());
     }
 
     public_libraries_ = base::Join(sonames, ':');
diff --git a/libutils/tests/Vector_test.cpp b/libutils/tests/Vector_test.cpp
index 671200f..e074a92 100644
--- a/libutils/tests/Vector_test.cpp
+++ b/libutils/tests/Vector_test.cpp
@@ -74,12 +74,9 @@
     EXPECT_EQ(other[3], 5);
 }
 
-// TODO: gtest isn't capable of parsing Abort messages formatted by
-// Android (fails differently on host and target), so we always need to
-// use an empty error message for death tests.
 TEST_F(VectorTest, SetCapacity_Overflow) {
   Vector<int> vector;
-  EXPECT_DEATH(vector.setCapacity(SIZE_MAX / sizeof(int) + 1), "");
+  EXPECT_DEATH(vector.setCapacity(SIZE_MAX / sizeof(int) + 1), "Assertion failed");
 }
 
 TEST_F(VectorTest, SetCapacity_ShrinkBelowSize) {
@@ -95,20 +92,13 @@
   ASSERT_EQ(8U, vector.capacity());
 }
 
-// NOTE: All of the tests below are useless because of the "TODO" above.
-// We have no way of knowing *why* the process crashed. Given that we're
-// inserting a NULL array, we'll fail with a SIGSEGV eventually. We need
-// the ability to make assertions on the abort message to make sure we're
-// failing for the right reasons.
 TEST_F(VectorTest, _grow_OverflowSize) {
   Vector<int> vector;
   vector.add(1);
 
   // Checks that the size calculation (not the capacity calculation) doesn't
   // overflow : the size here will be (1 + SIZE_MAX).
-  //
-  // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, SIZE_MAX), "new_size_overflow");
-  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, SIZE_MAX), "");
+  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, SIZE_MAX), "new_size overflow");
 }
 
 TEST_F(VectorTest, _grow_OverflowCapacityDoubling) {
@@ -116,18 +106,14 @@
 
   // This should fail because the calculated capacity will overflow even though
   // the size of the vector doesn't.
-  //
-  // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX - 1)), "new_capacity_overflow");
-  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX - 1)), "");
+  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX - 1)), "new_capacity overflow");
 }
 
 TEST_F(VectorTest, _grow_OverflowBufferAlloc) {
   Vector<int> vector;
   // This should fail because the capacity * sizeof(int) overflows, even
   // though the capacity itself doesn't.
-  //
-  // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX / 2)), "new_alloc_size overflow");
-  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX / 2)), "");
+  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX / 2)), "new_alloc_size overflow");
 }
 
 TEST_F(VectorTest, editArray_Shared) {