Merge "init: add host side parser for init"
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index f28302b..e5666bc 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -75,6 +75,11 @@
     usb_cleanup();
 }
 
+static void intentionally_leak() {
+    void* p = ::operator new(1);
+    LOG(INFO) << "leaking pointer " << p;
+}
+
 int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd) {
 #if defined(_WIN32)
     // adb start-server starts us up with stdout and stderr hooked up to
@@ -98,6 +103,11 @@
     });
 #endif
 
+    char* leak = getenv("ADB_LEAK");
+    if (leak && strcmp(leak, "1") == 0) {
+        intentionally_leak();
+    }
+
     if (is_daemon) {
         close_stdin();
         setup_daemon_logging();
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 32ed28f..a4c7a5a 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -62,9 +62,9 @@
 
 // The proc entry for / is full of lies, so check fstab instead.
 // /proc/mounts lists rootfs and /dev/root, neither of which is what we want.
-static std::string find_mount(const char* dir) {
-    if (strcmp(dir, "/") == 0) {
-       return find_fstab_mount(dir);
+static std::string find_mount(const char* dir, bool is_root) {
+    if (is_root) {
+        return find_fstab_mount(dir);
     } else {
        return find_proc_mount(dir);
     }
@@ -86,17 +86,29 @@
     if (!directory_exists(dir)) {
         return true;
     }
-    std::string dev = find_mount(dir);
-    if (dev.empty()) {
+    bool is_root = strcmp(dir, "/") == 0;
+    std::string dev = find_mount(dir, is_root);
+    // Even if the device for the root is not found, we still try to remount it
+    // as rw. This typically only happens when running Android in a container:
+    // the root will almost always be in a loop device, which is dynamic, so
+    // it's not convenient to put in the fstab.
+    if (dev.empty() && !is_root) {
         return true;
     }
-    if (!make_block_device_writable(dev)) {
+    if (!dev.empty() && !make_block_device_writable(dev)) {
         WriteFdFmt(fd, "remount of %s failed; couldn't make block device %s writable: %s\n",
                    dir, dev.c_str(), strerror(errno));
         return false;
     }
+    if (mount(dev.c_str(), dir, "none", MS_REMOUNT | MS_BIND, nullptr) == -1) {
+        // This is useful for cases where the superblock is already marked as
+        // read-write, but the mount itself is read-only, such as containers
+        // where the remount with just MS_REMOUNT is forbidden by the kernel.
+        WriteFdFmt(fd, "remount of the %s mount failed: %s.\n", dir, strerror(errno));
+        return false;
+    }
     if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) {
-        WriteFdFmt(fd, "remount of %s failed: %s\n", dir, strerror(errno));
+        WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno));
         return false;
     }
     return true;
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index b428dd7..caca377 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -20,7 +20,7 @@
     },
 }
 
-cc_library_shared {
+cc_library {
     name: "libmemunreachable",
     defaults: ["libmemunreachable_defaults"],
     srcs: [
@@ -88,14 +88,14 @@
 cc_test {
     name: "memunreachable_binder_test",
     defaults: ["libmemunreachable_defaults"],
+    test_suites: ["vts"],
     srcs: [
         "tests/Binder_test.cpp",
-        "tests/MemUnreachable_test.cpp",
     ],
+    static_libs: ["libmemunreachable"],
     shared_libs: [
         "libbinder",
         "libhwbinder",
-        "libmemunreachable",
         "libutils",
     ],
 }
diff --git a/libmemunreachable/tests/Binder_test.cpp b/libmemunreachable/tests/Binder_test.cpp
index 6e85d5a..eaf7652 100644
--- a/libmemunreachable/tests/Binder_test.cpp
+++ b/libmemunreachable/tests/Binder_test.cpp
@@ -33,6 +33,9 @@
 
 static const String16 service_name("test.libmemunreachable_binder");
 
+// Provides a service that will hold a strong reference to any remote binder
+// object, so that the test can verify that a remote strong reference is
+// visible to libmemunreachable.
 class BinderService : public BBinder {
  public:
   BinderService() = default;
@@ -55,6 +58,8 @@
   ~BinderObject() = default;
 };
 
+// Forks a subprocess that registers a BinderService with the global binder
+// servicemanager.  Requires root permissions.
 class ServiceProcess {
  public:
   ServiceProcess() : child_(0) {}
@@ -97,6 +102,7 @@
       fprintf(stderr, "Failed to get service manager\n");
       return 1;
     }
+    // This step requires root permissions
     if (sm->addService(service_name, new BinderService()) != OK) {
       fprintf(stderr, "Failed to add test service\n");
       return 1;
@@ -110,12 +116,18 @@
   pid_t child_;
 };
 
-class BinderTest : public ::testing::Test {
+class MemunreachableBinderTest : public ::testing::Test {
  protected:
   ServiceProcess service_process_;
 };
 
-TEST_F(BinderTest, binder) {
+// Tests that a local binder object with a remote strong reference is visible
+// through the libmemunreachable BinderReferences interface, which uses the
+// getBinderKernelReferences method in libbinder.  Starts a BinderService
+// through ServiceProcess as a remote service to hold the strong reference.
+TEST_F(MemunreachableBinderTest, binder) {
+  ASSERT_EQ(static_cast<uid_t>(0), getuid()) << "This test must be run as root.";
+
   ServiceProcess service_process;
   ASSERT_TRUE(service_process.Run());