linker: implement shared namespaces

Shared namespaces clone the list of loaded native
libraries from the caller namespace. This allows
classloaders for bundled apps to share already loaded
libraries with default namespace.

Bug: http://b/22548808
Bug: http://b/26165097
Change-Id: I8949d45937fdb38e1f586ff0679003adac0d9dad
(cherry picked from commit e78deef364d952dd1141a2f3067a12060aaf11e6)
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index ba54d39..a7c3fb0 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -148,12 +148,14 @@
 }
 
 android_namespace_t* android_create_namespace(const char* name, const char* ld_library_path,
-                                              const char* default_library_path, bool is_isolated,
+                                              const char* default_library_path, uint64_t type,
                                               const char* permitted_when_isolated_path) {
+  void* caller_addr = __builtin_return_address(0);
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
 
-  android_namespace_t* result = create_namespace(name, ld_library_path, default_library_path,
-                                                 is_isolated, permitted_when_isolated_path);
+  android_namespace_t* result = create_namespace(caller_addr, name, ld_library_path,
+                                                 default_library_path, type,
+                                                 permitted_when_isolated_path);
 
   if (result == nullptr) {
     __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer());
diff --git a/linker/linker.cpp b/linker/linker.cpp
index e38e252..eb938c7 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1747,7 +1747,6 @@
   });
 
   return true;
-
 }
 
 static bool load_library(android_namespace_t* ns,
@@ -2377,8 +2376,12 @@
   g_public_namespace_initialized = true;
 
   // create anonymous namespace
+  // When the caller is nullptr - create_namespace will take global group
+  // from the anonymous namespace, which is fine because anonymous namespace
+  // is still pointing to the default one.
   android_namespace_t* anon_ns =
-      create_namespace("(anonymous)", nullptr, anon_ns_library_path, false, nullptr);
+      create_namespace(nullptr, "(anonymous)", nullptr, anon_ns_library_path,
+                       ANDROID_NAMESPACE_TYPE_REGULAR, nullptr);
 
   if (anon_ns == nullptr) {
     g_public_namespace_initialized = false;
@@ -2389,16 +2392,23 @@
   return true;
 }
 
-android_namespace_t* create_namespace(const char* name,
+android_namespace_t* create_namespace(const void* caller_addr,
+                                      const char* name,
                                       const char* ld_library_path,
                                       const char* default_library_path,
-                                      bool is_isolated,
+                                      uint64_t type,
                                       const char* permitted_when_isolated_path) {
   if (!g_public_namespace_initialized) {
     DL_ERR("cannot create namespace: public namespace is not initialized.");
     return nullptr;
   }
 
+  soinfo* caller_soinfo = find_containing_library(caller_addr);
+
+  android_namespace_t* caller_ns = caller_soinfo != nullptr ?
+                                   caller_soinfo->get_namespace() :
+                                   g_anonymous_namespace;
+
   ProtectedDataGuard guard;
   std::vector<std::string> ld_library_paths;
   std::vector<std::string> default_library_paths;
@@ -2410,14 +2420,20 @@
 
   android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
   ns->set_name(name);
-  ns->set_isolated(is_isolated);
+  ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
   ns->set_ld_library_paths(std::move(ld_library_paths));
   ns->set_default_library_paths(std::move(default_library_paths));
   ns->set_permitted_paths(std::move(permitted_paths));
 
-  // TODO(dimtiry): Should this be global group of caller's namespace?
-  auto global_group = make_global_group(&g_default_namespace);
-  std::copy(global_group.begin(), global_group.end(), std::back_inserter(ns->soinfo_list()));
+  if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
+    // If shared - clone the caller namespace
+    auto& soinfo_list = caller_ns->soinfo_list();
+    std::copy(soinfo_list.begin(), soinfo_list.end(), std::back_inserter(ns->soinfo_list()));
+  } else {
+    // If not shared - copy only the global group
+    auto global_group = make_global_group(caller_ns);
+    std::copy(global_group.begin(), global_group.end(), std::back_inserter(ns->soinfo_list()));
+  }
 
   return ns;
 }
diff --git a/linker/linker.h b/linker/linker.h
index 5ec259e..5a06853 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -444,8 +444,8 @@
 uint32_t get_application_target_sdk_version();
 
 bool init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path);
-android_namespace_t* create_namespace(const char* name, const char* ld_library_path,
-                                      const char* default_library_path, bool is_isolated,
-                                      const char* permitted_when_isolated_path);
+android_namespace_t* create_namespace(const void* caller_addr, const char* name,
+                                      const char* ld_library_path, const char* default_library_path,
+                                      uint64_t type, const char* permitted_when_isolated_path);
 
 #endif
diff --git a/linker/linker_debug.h b/linker/linker_debug.h
index 17c6986..5af9929 100644
--- a/linker/linker_debug.h
+++ b/linker/linker_debug.h
@@ -55,6 +55,7 @@
  *********************************************************************/
 
 #include "private/libc_logging.h"
+#include <unistd.h>
 
 __LIBC_HIDDEN__ extern int g_ld_debug_verbosity;