greylist is no longer enabled by default.

greylist is needed only for application namepaces. Since we started using
linker-namesapces for vendors and other platform apps linker should not
enable greylist workaround by default.

Bug: http://b/37731053
Bug: https://issuetracker.google.com/38146125
Test: sailfish builds and boots
Test: bionic-unit-tests and linker-unit-tests pass
Change-Id: Iee83db6fb1ae754f5ade18491321d9bca3b5ead4
(cherry picked from commit e8ffe56a9c2bacc6bd880238250ad61e2bbb257b)
diff --git a/linker/linker.cpp b/linker/linker.cpp
index cd2c55b..8e7a141 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1080,7 +1080,7 @@
   }
 
   // TODO(dimitry): workaround for http://b/26394120 (the grey-list)
-  if (fd == -1 && ns != &g_default_namespace && is_greylisted(ns, name, needed_by)) {
+  if (fd == -1 && ns->is_greylist_enabled() && is_greylisted(ns, name, needed_by)) {
     // try searching for it on default_namespace default_library_path
     fd = open_library_on_paths(zip_archive_cache, name, file_offset,
                                g_default_namespace.get_default_library_paths(), realpath);
@@ -2184,6 +2184,7 @@
   android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
   ns->set_name(name);
   ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
+  ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0);
 
   if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
     // append parent namespace paths.
diff --git a/linker/linker.h b/linker/linker.h
index fdd7b66..ae1ae3c 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -155,6 +155,12 @@
    * permitted_path from the caller's namespace.
    */
   ANDROID_NAMESPACE_TYPE_SHARED = 2,
+
+  /* This flag instructs linker to enable grey-list workaround for the namespace.
+   * See http://b/26394120 for details.
+   */
+  ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
+
   ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
                                            ANDROID_NAMESPACE_TYPE_ISOLATED,
 };
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index c3260fd..1099b6b 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -63,7 +63,7 @@
 
 struct android_namespace_t {
  public:
-  android_namespace_t() : name_(nullptr), is_isolated_(false) {}
+  android_namespace_t() : name_(nullptr), is_isolated_(false), is_greylist_enabled_(false) {}
 
   const char* get_name() const { return name_; }
   void set_name(const char* name) { name_ = name; }
@@ -71,6 +71,9 @@
   bool is_isolated() const { return is_isolated_; }
   void set_isolated(bool isolated) { is_isolated_ = isolated; }
 
+  bool is_greylist_enabled() const { return is_greylist_enabled_; }
+  void set_greylist_enabled(bool enabled) { is_greylist_enabled_ = enabled; }
+
   const std::vector<std::string>& get_ld_library_paths() const {
     return ld_library_paths_;
   }
@@ -136,6 +139,7 @@
  private:
   const char* name_;
   bool is_isolated_;
+  bool is_greylist_enabled_;
   std::vector<std::string> ld_library_paths_;
   std::vector<std::string> default_library_paths_;
   std::vector<std::string> permitted_paths_;
diff --git a/tests/dlext_private.h b/tests/dlext_private.h
index 6b943ce..dea92ee 100644
--- a/tests/dlext_private.h
+++ b/tests/dlext_private.h
@@ -55,6 +55,12 @@
    * permitted_path from the caller's namespace.
    */
   ANDROID_NAMESPACE_TYPE_SHARED = 2,
+
+  /* This flag instructs linker to enable grey-list workaround for the namespace.
+   * See http://b/26394120 for details.
+   */
+  ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
+
   ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
                                            ANDROID_NAMESPACE_TYPE_ISOLATED,
 };
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index cf642cd..e3ee7d7 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -1050,7 +1050,7 @@
             "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
 }
 
-TEST(dlext, ns_greylist) {
+TEST(dlext, ns_greylist_enabled) {
   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
 
   const std::string ns_search_path = get_testlib_root() + "/private_namespace_libs";
@@ -1059,7 +1059,7 @@
           android_create_namespace("namespace",
                                    nullptr,
                                    ns_search_path.c_str(),
-                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED,
                                    nullptr,
                                    nullptr);
 
@@ -1088,6 +1088,31 @@
   ASSERT_STREQ("dlopen failed: library \"libnativehelper.so\" not found", dlerror());
 }
 
+TEST(dlext, ns_greylist_disabled_by_default) {
+  ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
+
+  const std::string ns_search_path = get_testlib_root() + "/private_namespace_libs";
+
+  android_namespace_t* ns =
+          android_create_namespace("namespace",
+                                   nullptr,
+                                   ns_search_path.c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   nullptr,
+                                   nullptr);
+
+  ASSERT_TRUE(android_link_namespaces(ns, nullptr, g_core_shared_libs.c_str())) << dlerror();
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns;
+
+  android_set_application_target_sdk_version(__ANDROID_API_M__);
+  void* handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle == nullptr);
+  ASSERT_STREQ("dlopen failed: library \"libnativehelper.so\" not found", dlerror());
+}
+
 TEST(dlext, ns_cyclic_namespaces) {
   // Test that ns1->ns2->ns1 link does not break the loader
   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));