Merge "Rename target.linux[_x86[_64]] to target.linux_glibc[_x86[_64]]" am: c6021960a4 am: 735fef090d
am: c423d7afec

Change-Id: Ibb8b2bbc1fa73c44313ec52e996a7f10de152029
diff --git a/linker/linker.cpp b/linker/linker.cpp
index f6ca430..f3d4a67 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1156,6 +1156,27 @@
   return *candidate != nullptr;
 }
 
+static bool find_loaded_library_by_realpath(android_namespace_t* ns, const char* realpath,
+                                            bool search_linked_namespaces, soinfo** candidate) {
+  auto predicate = [&](soinfo* si) { return strcmp(realpath, si->get_realpath()) == 0; };
+
+  *candidate = ns->soinfo_list().find_if(predicate);
+
+  if (*candidate == nullptr && search_linked_namespaces) {
+    for (auto& link : ns->linked_namespaces()) {
+      android_namespace_t* linked_ns = link.linked_namespace();
+      soinfo* si = linked_ns->soinfo_list().find_if(predicate);
+
+      if (si != nullptr && link.is_accessible(si->get_soname())) {
+        *candidate = si;
+        return true;
+      }
+    }
+  }
+
+  return *candidate != nullptr;
+}
+
 static bool load_library(android_namespace_t* ns,
                          LoadTask* task,
                          LoadTaskList* load_tasks,
@@ -1974,12 +1995,18 @@
 
   const char* translated_name = name;
   if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') {
-    char translated_path[PATH_MAX];
-    if (realpath(translated_name, translated_path) != nullptr) {
-      asan_name_holder = std::string(kAsanLibDirPrefix) + translated_path;
+    char original_path[PATH_MAX];
+    if (realpath(name, original_path) != nullptr) {
+      asan_name_holder = std::string(kAsanLibDirPrefix) + original_path;
       if (file_exists(asan_name_holder.c_str())) {
-        translated_name = asan_name_holder.c_str();
-        PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+        soinfo* si = nullptr;
+        if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
+          PRINT("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
+                asan_name_holder.c_str());
+        } else {
+          PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+          translated_name = asan_name_holder.c_str();
+        }
       }
     }
   }
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index f6d5072..e036c05 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -375,15 +375,6 @@
                                       bool is_asan,
                                       const Config** config,
                                       std::string* error_msg) {
-  // TODO(b/38114603) Currently, multiple namespaces does not support ASAN mode
-  // where some symbols should be intercepted via LD_PRELOAD; LD_PRELOADed libs
-  // are not being preloaded into the linked namespaces other than the default
-  // namespace. Until we fix the problem, we temporarily disable ld.config.txt
-  // in ASAN mode.
-  if (is_asan) {
-    return false;
-  }
-
   g_config.clear();
 
   std::unordered_map<std::string, PropertyValue> property_map;
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index 87609d0..c6fade9 100644
--- a/linker/tests/linker_config_test.cpp
+++ b/linker/tests/linker_config_test.cpp
@@ -168,7 +168,6 @@
   run_linker_config_smoke_test(false);
 }
 
-// TODO(b/38114603) revive this test when ld.config.txt is enabled for ASAN mode
-//TEST(linker_config, asan_smoke) {
-//  run_linker_config_smoke_test(true);
-//}
+TEST(linker_config, asan_smoke) {
+  run_linker_config_smoke_test(true);
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index da56367..25af05e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -328,12 +328,6 @@
             ],
         }
     },
-
-    product_variables: {
-        debuggable: {
-            cppflags: ["-DUSE_LD_CONFIG_FILE"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -624,12 +618,6 @@
     sanitize: {
         never: false,
     },
-
-    product_variables: {
-        debuggable: {
-            cppflags: ["-DUSE_LD_CONFIG_FILE"],
-        },
-    },
 }
 
 subdirs = ["libs"]
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index ceb0b4d..2133a2c 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -180,12 +180,24 @@
 }
 #endif
 
-#ifdef USE_LD_CONFIG_FILE
+#if defined(__BIONIC__)
+static bool is_user_build() {
+  std::string build_type = android::base::GetProperty("ro.build.type", "user");
+  if (build_type == "userdebug" || build_type == "eng") {
+    return false;
+  }
+  return true;
+}
+#endif
 
 // _lib1.so and _lib2.so are now searchable by having another namespace 'ns2'
 // whose search paths include the 'ns2/' subdir.
 TEST(dl, exec_with_ld_config_file) {
 #if defined(__BIONIC__)
+  if (is_user_build()) {
+    // LD_CONFIG_FILE is not supported on user build
+    return;
+  }
   std::string helper = get_testlib_root() +
       "/ld_config_test_helper/ld_config_test_helper";
   std::string config_file = get_testlib_root() + "/ld.config.txt";
@@ -204,6 +216,10 @@
 // additional namespaces other than the default namespace.
 TEST(dl, exec_with_ld_config_file_with_ld_preload) {
 #if defined(__BIONIC__)
+  if (is_user_build()) {
+    // LD_CONFIG_FILE is not supported on user build
+    return;
+  }
   std::string helper = get_testlib_root() +
       "/ld_config_test_helper/ld_config_test_helper";
   std::string config_file = get_testlib_root() + "/ld.config.txt";
@@ -218,8 +234,6 @@
 #endif
 }
 
-#endif // USE_LD_CONFIG_FILE
-
 // ensures that LD_CONFIG_FILE env var does not work for production builds.
 // The test input is the same as exec_with_ld_config_file, but it must fail in
 // this case.
@@ -230,8 +244,7 @@
     // This test is only for CTS.
     return;
   }
-  std::string build_type = android::base::GetProperty("ro.build.type", "user");
-  if (build_type == "userdebug" || build_type == "eng") {
+  if (!is_user_build()) {
     // Skip the test for non production devices
     return;
   }
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 0dc54d0..63e2d8e 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -1270,29 +1270,49 @@
 
   std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
 
+  // create a parent namespace to use instead of the default namespace. This is
+  // to make this test be independent from the configuration of the default
+  // namespace.
+  android_namespace_t* ns_parent =
+          android_create_namespace("parent",
+                                   nullptr,
+                                   nullptr,
+                                   ANDROID_NAMESPACE_TYPE_REGULAR,
+                                   nullptr,
+                                   nullptr);
+  ASSERT_TRUE(ns_parent != nullptr) << dlerror();
+  ASSERT_TRUE(android_link_namespaces(ns_parent, nullptr, g_core_shared_libs.c_str())) << dlerror();
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_parent;
+
   const std::string lib_public_path = get_testlib_root() + "/public_namespace_libs/" + g_public_lib;
-  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+  void* handle_public = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
   ASSERT_TRUE(handle_public != nullptr) << dlerror();
 
   android_set_application_target_sdk_version(42U); // something > 23
 
   ASSERT_TRUE(android_init_anonymous_namespace(shared_libs.c_str(), nullptr)) << dlerror();
 
-  // preload this library to the default namespace to check if it
+  // preload this library to the parent namespace to check if it
   // is shared later on.
   void* handle_dlopened =
-          dlopen((get_testlib_root() + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW);
+          android_dlopen_ext((get_testlib_root() + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW, &extinfo);
   ASSERT_TRUE(handle_dlopened != nullptr) << dlerror();
 
+  // create two child namespaces of 'ns_parent'. One with regular, the other
+  // with isolated & shared.
   android_namespace_t* ns_not_isolated =
           android_create_namespace("private",
                                    nullptr,
                                    (get_testlib_root() + "/private_namespace_libs").c_str(),
                                    ANDROID_NAMESPACE_TYPE_REGULAR,
                                    nullptr,
-                                   nullptr);
+                                   ns_parent);
   ASSERT_TRUE(ns_not_isolated != nullptr) << dlerror();
-  ASSERT_TRUE(android_link_namespaces(ns_not_isolated, nullptr, shared_libs.c_str())) << dlerror();
+  ASSERT_TRUE(android_link_namespaces(ns_not_isolated, ns_parent, g_public_lib)) << dlerror();
+  ASSERT_TRUE(android_link_namespaces(ns_not_isolated, nullptr, g_core_shared_libs.c_str())) << dlerror();
 
   android_namespace_t* ns_isolated_shared =
           android_create_namespace("private_isolated_shared",
@@ -1300,23 +1320,22 @@
                                    (get_testlib_root() + "/private_namespace_libs").c_str(),
                                    ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_SHARED,
                                    nullptr,
-                                   nullptr);
+                                   ns_parent);
   ASSERT_TRUE(ns_isolated_shared != nullptr) << dlerror();
-  ASSERT_TRUE(android_link_namespaces(ns_isolated_shared, nullptr, shared_libs.c_str())) << dlerror();
+  ASSERT_TRUE(android_link_namespaces(ns_isolated_shared, ns_parent, g_public_lib)) << dlerror();
+  ASSERT_TRUE(android_link_namespaces(ns_isolated_shared, nullptr, g_core_shared_libs.c_str())) << dlerror();
 
-  ASSERT_TRUE(dlopen(root_lib, RTLD_NOW) == nullptr);
+  ASSERT_TRUE(android_dlopen_ext(root_lib, RTLD_NOW, &extinfo) == nullptr);
   ASSERT_STREQ("dlopen failed: library \"libnstest_root_not_isolated.so\" not found", dlerror());
 
   std::string lib_private_external_path =
       get_testlib_root() + "/private_namespace_libs_external/libnstest_private_external.so";
 
-  // Load lib_private_external_path to default namespace
+  // Load lib_private_external_path to the parent namespace
   // (it should remain invisible for the isolated namespaces after this)
-  void* handle = dlopen(lib_private_external_path.c_str(), RTLD_NOW);
+  void* handle = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
   ASSERT_TRUE(handle != nullptr) << dlerror();
 
-  android_dlextinfo extinfo;
-  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   extinfo.library_namespace = ns_not_isolated;
 
   void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 8af2263..cd51e1b 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -784,12 +784,6 @@
   EXPECT_GT(_XOPEN_IOV_MAX, 0);
   EXPECT_GT(_XOPEN_UNIX, 0);
 
-  // In O, the headers still have -1 (even though all the functionality has
-  // been there for a long time). This was fixed in O-DR, but there isn't a
-  // separate CTS for O-DR, so we'll accept both.
-  EXPECT_TRUE(_POSIX_THREAD_PROCESS_SHARED == -1 ||
-              _POSIX_THREAD_PROCESS_SHARED == _POSIX_VERSION);
-
 #if defined(__BIONIC__)
   // These tests only pass on bionic, as bionic and glibc has different support on these macros.
   // Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet.