Merge "Reland: Fix libnativeloader to correctly link to the platform namespace."
am: 2d3becd361

Change-Id: Ic9317fd3fceaecbba61840e37ad12f9cb2daaa51
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index e460b1a..1012ea0 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -126,7 +126,7 @@
 // classloader, the classloader-namespace namespace associated with that
 // classloader is selected for dlopen. The namespace is configured so that its
 // search path is set to the app-local JNI directory and it is linked to the
-// default namespace with the names of libs listed in the public.libraries.txt.
+// platform namespace with the names of libs listed in the public.libraries.txt.
 // This way an app can only load its own JNI libraries along with the public libs.
 static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
 // Same thing for vendor APKs.
@@ -309,21 +309,24 @@
       }
     }
 
-    std::string runtime_exposed_libraries = base::Join(kRuntimePublicLibraries, ":");
+    std::string runtime_exposed_libraries = runtime_public_libraries_;
 
     NativeLoaderNamespace native_loader_ns;
     if (!is_native_bridge) {
+      // The platform namespace is called "default" for binaries in /system and
+      // "platform" for those in the Runtime APEX. Try "platform" first since
+      // "default" always exists.
+      android_namespace_t* platform_ns = android_get_exported_namespace(kPlatformNamespaceName);
+      if (platform_ns == nullptr) {
+        platform_ns = android_get_exported_namespace(kDefaultNamespaceName);
+      }
+
       android_namespace_t* android_parent_ns;
       if (parent_ns != nullptr) {
         android_parent_ns = parent_ns->get_android_ns();
       } else {
-        // Fall back to the platform namespace if no parent is found. It is
-        // called "default" for binaries in /system and "platform" for those in
-        // the Runtime APEX. Try "platform" first since "default" always exists.
-        android_parent_ns = android_get_exported_namespace(kPlatformNamespaceName);
-        if (android_parent_ns == nullptr) {
-          android_parent_ns = android_get_exported_namespace(kDefaultNamespaceName);
-        }
+        // Fall back to the platform namespace if no parent is found.
+        android_parent_ns = platform_ns;
       }
 
       android_namespace_t* ns = android_create_namespace(namespace_name,
@@ -344,7 +347,7 @@
 
       android_namespace_t* runtime_ns = android_get_exported_namespace(kRuntimeNamespaceName);
 
-      if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
+      if (!android_link_namespaces(ns, platform_ns, system_exposed_libraries.c_str())) {
         *error_msg = dlerror();
         return nullptr;
       }
@@ -374,14 +377,19 @@
 
       native_loader_ns = NativeLoaderNamespace(ns);
     } else {
+      // Same functionality as in the branch above, but calling through native bridge.
+
+      native_bridge_namespace_t* platform_ns =
+          NativeBridgeGetExportedNamespace(kPlatformNamespaceName);
+      if (platform_ns == nullptr) {
+        platform_ns = NativeBridgeGetExportedNamespace(kDefaultNamespaceName);
+      }
+
       native_bridge_namespace_t* native_bridge_parent_namespace;
       if (parent_ns != nullptr) {
         native_bridge_parent_namespace = parent_ns->get_native_bridge_ns();
       } else {
-        native_bridge_parent_namespace = NativeBridgeGetExportedNamespace(kPlatformNamespaceName);
-        if (native_bridge_parent_namespace == nullptr) {
-          native_bridge_parent_namespace = NativeBridgeGetExportedNamespace(kDefaultNamespaceName);
-        }
+        native_bridge_parent_namespace = platform_ns;
       }
 
       native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
@@ -399,7 +407,7 @@
       native_bridge_namespace_t* runtime_ns =
           NativeBridgeGetExportedNamespace(kRuntimeNamespaceName);
 
-      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
+      if (!NativeBridgeLinkNamespaces(ns, platform_ns, system_exposed_libraries.c_str())) {
         *error_msg = NativeBridgeGetError();
         return nullptr;
       }
@@ -451,6 +459,7 @@
     std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
     std::string public_native_libraries_system_config =
             root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
+    std::string runtime_public_libraries = base::Join(kRuntimePublicLibraries, ":");
     std::string llndk_native_libraries_system_config =
             root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
     std::string vndksp_native_libraries_system_config =
@@ -472,6 +481,10 @@
         std::vector<std::string> additional_libs_vector = base::Split(additional_libs, ":");
         std::copy(additional_libs_vector.begin(), additional_libs_vector.end(),
                   std::back_inserter(sonames));
+        // Apply the same list to the runtime namespace, since some libraries
+        // might reside there.
+        CHECK(sizeof(kRuntimePublicLibraries) > 0);
+        runtime_public_libraries = runtime_public_libraries + ':' + additional_libs;
       }
     }
 
@@ -497,6 +510,7 @@
     }
 
     system_public_libraries_ = base::Join(sonames, ':');
+    runtime_public_libraries_ = runtime_public_libraries;
 
     // read /system/etc/public.libraries-<companyname>.txt which contain partner defined
     // system libs that are exposed to apps. The libs in the txt files must be
@@ -724,6 +738,7 @@
   bool initialized_;
   std::list<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
   std::string system_public_libraries_;
+  std::string runtime_public_libraries_;
   std::string vendor_public_libraries_;
   std::string oem_public_libraries_;
   std::string product_public_libraries_;
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index 485bc75..4b07478 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -20,6 +20,9 @@
 
 [legacy]
 namespace.default.isolated = false
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
 
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /product/${LIB}
@@ -41,7 +44,7 @@
 
 additional.namespaces = runtime,conscrypt,media,resolv
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 # If a shared library or an executable requests a shared library that
 # cannot be loaded into the default namespace, the dynamic linker tries
 # to load the shared library from the runtime namespace. And then, if the
@@ -50,9 +53,6 @@
 # Finally, if all attempts fail, the dynamic linker returns an error.
 namespace.default.links = runtime,resolv
 namespace.default.asan.links = runtime,resolv
-# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
-# libart.
-namespace.default.visible = true
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -72,11 +72,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -120,11 +122,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 264fbf4..f4710d8 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -43,6 +43,9 @@
 # can't be loaded in this namespace.
 ###############################################################################
 namespace.default.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
 
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /%PRODUCT%/${LIB}
@@ -121,7 +124,7 @@
 namespace.default.asan.permitted.paths += /apex/com.android.runtime/${LIB}/bionic
 namespace.default.asan.permitted.paths += /system/${LIB}/bootstrap
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 # If a shared library or an executable requests a shared library that
 # cannot be loaded into the default namespace, the dynamic linker tries
 # to load the shared library from the runtime namespace. And then, if the
@@ -129,9 +132,6 @@
 # dynamic linker tries to load the shared library from the resolv namespace.
 # Finally, if all attempts fail, the dynamic linker returns an error.
 namespace.default.links = runtime,resolv
-# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
-# libart.
-namespace.default.visible = true
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -151,11 +151,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -188,11 +190,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
@@ -235,6 +237,8 @@
 # Note that there is no link from the default namespace to this namespace.
 ###############################################################################
 namespace.sphal.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.sphal.visible = true
 
 namespace.sphal.search.paths  = /odm/${LIB}
@@ -324,6 +328,8 @@
 # This namespace is exclusively for vndk-sp libs.
 ###############################################################################
 namespace.vndk.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.vndk.visible = true
 
 namespace.vndk.search.paths  = /odm/${LIB}/vndk-sp
@@ -431,10 +437,10 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = system
@@ -566,6 +572,10 @@
 [unrestricted]
 additional.namespaces = runtime,media,conscrypt,resolv
 
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
+
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /odm/${LIB}
 namespace.default.search.paths += /vendor/${LIB}
@@ -577,10 +587,8 @@
 namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
 namespace.default.asan.search.paths +=           /vendor/${LIB}
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 namespace.default.links = runtime,resolv
-namespace.default.visible = true
-
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -597,11 +605,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -632,11 +642,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 02b1bfa..4ce7f52 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -43,6 +43,9 @@
 # partitions are also allowed temporarily.
 ###############################################################################
 namespace.default.isolated = false
+# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
+# libart.
+namespace.default.visible = true
 
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /odm/${LIB}
@@ -61,8 +64,7 @@
 namespace.default.asan.search.paths += /data/asan/%PRODUCT_SERVICES%/${LIB}
 namespace.default.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
-# Keep in sync with the platform namespace in the com.android.runtime APEX
-# ld.config.txt.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 # If a shared library or an executable requests a shared library that
 # cannot be loaded into the default namespace, the dynamic linker tries
 # to load the shared library from the runtime namespace. And then, if the
@@ -70,9 +72,6 @@
 # dynamic linker tries to load the shared library from the resolv namespace.
 # Finally, if all attempts fail, the dynamic linker returns an error.
 namespace.default.links = runtime,resolv
-# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
-# libart.
-namespace.default.visible = true
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -92,12 +91,13 @@
 # "runtime" APEX namespace
 #
 # This namespace pulls in externally accessible libs from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with the default namespace in the com.android.runtime APEX
-# ld.config.txt.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -130,11 +130,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
@@ -177,6 +177,8 @@
 # Note that there is no link from the default namespace to this namespace.
 ###############################################################################
 namespace.sphal.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.sphal.visible = true
 
 namespace.sphal.search.paths  = /odm/${LIB}
@@ -266,6 +268,8 @@
 # This namespace is exclusively for vndk-sp libs.
 ###############################################################################
 namespace.vndk.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.vndk.visible = true
 
 namespace.vndk.search.paths  = /odm/${LIB}/vndk-sp
@@ -369,10 +373,10 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -389,6 +393,10 @@
 [unrestricted]
 additional.namespaces = runtime,media,conscrypt,resolv
 
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
+
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /odm/${LIB}
 namespace.default.search.paths += /vendor/${LIB}
@@ -400,10 +408,8 @@
 namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
 namespace.default.asan.search.paths +=           /vendor/${LIB}
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 namespace.default.links = runtime,resolv
-namespace.default.visible = true
-
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -420,11 +426,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -455,11 +463,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default