Snap for 11224086 from a588cc1e19f4f6992bf2dc6ce50825d1f1d48b52 to mainline-tzdata5-release

Change-Id: Ie8693623923663a6c94c3a3b5ee7cb7a525ab67f
diff --git a/tests/native/Android.bp b/tests/native/Android.bp
index 7915222..879c885 100644
--- a/tests/native/Android.bp
+++ b/tests/native/Android.bp
@@ -34,11 +34,12 @@
     },
 
     shared_libs: [
-        "libbase",
         "liblog",
+        "libdl_android",
     ],
 
     static_libs: [
+        "libbase",
         "libc++fs",
         "libfs_mgr",
     ],
diff --git a/tests/native/apex_shared_libraries_test.cpp b/tests/native/apex_shared_libraries_test.cpp
index 9f536dc..e68e5c9 100644
--- a/tests/native/apex_shared_libraries_test.cpp
+++ b/tests/native/apex_shared_libraries_test.cpp
@@ -19,6 +19,7 @@
 #include <android-base/properties.h>
 #include <android-base/scopeguard.h>
 #include <android-base/strings.h>
+#include <android/dlext.h>
 #include <dlfcn.h>
 #include <fstab/fstab.h>
 #include <gtest/gtest.h>
@@ -26,6 +27,7 @@
 
 #include <filesystem>
 #include <fstream>
+#include <regex>
 #include <string>
 
 using android::base::GetBoolProperty;
@@ -36,8 +38,23 @@
 
 namespace fs = std::filesystem;
 
-static constexpr const char* kApexRoot = "/apex";
-static constexpr const char* kApexSharedLibsRoot = "/apex/sharedlibs";
+// No header available for these symbols
+extern "C" struct android_namespace_t* android_get_exported_namespace(
+    const char* name);
+
+extern "C" struct android_namespace_t* android_create_namespace(
+    const char* name, const char* ld_library_path,
+    const char* default_library_path, uint64_t type,
+    const char* permitted_when_isolated_path,
+    struct android_namespace_t* parent);
+
+#if !defined(__LP64__)
+static constexpr const char LIB[] = "lib";
+#else   // !__LP64__
+static constexpr const char LIB[] = "lib64";
+#endif  // !__LP64_
+
+static constexpr const char kApexSharedLibsRoot[] = "/apex/sharedlibs";
 
 TEST(apex_shared_libraries, symlink_libraries_loadable) {
   if (!GetBoolProperty("ro.apex.updatable", false)) {
@@ -47,31 +64,32 @@
   Fstab fstab;
   ASSERT_TRUE(ReadFstabFromFile("/proc/mounts", &fstab));
 
+  // Regex to use when checking if a mount is for an active APEX or not. Note
+  // that non-active APEX mounts don't have the @<number> marker.
+  std::regex active_apex_pattern(R"(/apex/(.*)@\d+)");
+
   // Traverse mount points to identify apexs.
   for (auto& entry : fstab) {
-    if (fs::path(entry.mount_point).parent_path() != kApexRoot) {
+    std::cmatch m;
+    if (!std::regex_match(entry.mount_point.c_str(), m, active_apex_pattern)) {
       continue;
     }
-
-    // Focus on "active" apexs.
-    if (entry.mount_point.find('@') != std::string::npos) {
-      continue;
-    }
-    std::string dev_file = fs::path(entry.blk_device).filename();
+    // Linker namespace name of the apex com.android.foo is com_android_foo.
+    std::string apex_namespace_name = m[1];
+    std::replace(apex_namespace_name.begin(), apex_namespace_name.end(), '.',
+                 '_');
 
     // Filter out any mount irrelevant (e.g. tmpfs)
+    std::string dev_file = fs::path(entry.blk_device).filename();
     if (!StartsWith(dev_file, "loop") && !StartsWith(dev_file, "dm-")) {
       continue;
     }
 
-#if !defined(__LP64__)
-    auto lib = fs::path(entry.mount_point) / "lib";
-#else   // !__LP64__
-    auto lib = fs::path(entry.mount_point) / "lib64";
-#endif  // !__LP64__
+    auto lib = fs::path(entry.mount_point) / LIB;
     if (!fs::is_directory(lib)) {
       continue;
     }
+
     for (auto& p : fs::directory_iterator(lib)) {
       std::error_code ec;
       if (!fs::is_symlink(p, ec)) {
@@ -95,7 +113,38 @@
 
       // Library loading validity check.
       dlerror();  // Clear any pending errors.
-      void* handle = dlopen(p.path().c_str(), RTLD_NOW);
+      android_namespace_t* ns =
+          android_get_exported_namespace(apex_namespace_name.c_str());
+      if (ns == nullptr) {
+        // In case the apex namespace doesn't exist (actually not accessible),
+        // create a new one that can search libraries from the apex directory
+        // and can load (but not search) from the shared lib APEX.
+        std::string search_paths = lib;
+        search_paths.push_back(':');
+        // Adding "/system/lib[64]" is not ideal; we need to link to the
+        // namespace that is capable of loading libs from the directory.
+        // However, since the namespace (the `system` namespace) is not
+        // exported, we can't make a link. Instead, we allow this new namespace
+        // to search/load libraries from the directory.
+        search_paths.append(std::string("/system/") + LIB);
+        std::string permitted_paths = "/apex";
+        ns = android_create_namespace(
+            apex_namespace_name.c_str(),
+            /* ld_library_path=*/nullptr,
+            /* default_library_path=*/search_paths.c_str(),
+            /* type=*/3,  // ISOLATED and SHARED
+            /* permitted_when_isolated_path=*/permitted_paths.c_str(),
+            /* parent=*/nullptr);
+      }
+
+      EXPECT_TRUE(ns != nullptr)
+          << "Cannot find namespace " << apex_namespace_name;
+      const android_dlextinfo dlextinfo = {
+          .flags = ANDROID_DLEXT_USE_NAMESPACE,
+          .library_namespace = ns,
+      };
+
+      void* handle = android_dlopen_ext(p.path().c_str(), RTLD_NOW, &dlextinfo);
       EXPECT_TRUE(handle != nullptr) << dlerror();
       if (handle == nullptr) {
         continue;