Merge "Defend against -fstack-protector in libc startup." am: 195b85a80f
am: 6e499bc37d

* commit '6e499bc37d9caa8c914a8f83345bc2b2d8ae8132':
  Defend against -fstack-protector in libc startup.
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 841ad16..9421e26 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -48,6 +48,11 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libc_*)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libc_*)
 
+# Required due to the replacement of a symlink with a shared library
+# (commit b952f42bef69e5c in frameworks/native).
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib/libGLES*)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib64/libGLES*)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/libc/upstream-netbsd/android/include/netbsd-compat.h b/libc/upstream-netbsd/android/include/netbsd-compat.h
index 8d1c46b..0212d16 100644
--- a/libc/upstream-netbsd/android/include/netbsd-compat.h
+++ b/libc/upstream-netbsd/android/include/netbsd-compat.h
@@ -32,6 +32,6 @@
 #define __unlockenv() 0
 
 #include <stddef.h>
-__LIBC_HIDDEN__ int reallocarr(void*, size_t, size_t);
+int reallocarr(void*, size_t, size_t);
 
 #endif
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 70c2ca5..de0da56 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -153,6 +153,47 @@
   nullptr
 };
 
+static bool is_system_library(const std::string& realpath) {
+  for (const auto& dir : g_default_namespace.get_default_library_paths()) {
+    if (file_is_in_dir(realpath, dir)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// TODO(dimitry): This is workaround for http://b/26394120 - it will be removed before the release
+static bool is_greylisted(const char* name, const soinfo* needed_by) {
+  static const char* const kLibraryGreyList[] = {
+    "libandroid_runtime.so",
+    "libbinder.so",
+    "libcrypto.so",
+    "libcutils.so",
+    "libmedia.so",
+    "libnativehelper.so",
+    "libssl.so",
+    "libstagefright.so",
+    "libutils.so",
+    nullptr
+  };
+
+  // if the library needed by a system library - implicitly assume it
+  // is greylisted
+
+  if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) {
+    return true;
+  }
+
+  for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) {
+    if (strcmp(name, kLibraryGreyList[i]) == 0) {
+      return true;
+    }
+  }
+
+  return false;
+}
+// END OF WORKAROUND
+
 static const ElfW(Versym) kVersymNotNeeded = 0;
 static const ElfW(Versym) kVersymGlobal = 1;
 
@@ -1608,6 +1649,14 @@
     fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
   }
 
+  // TODO(dimitry): workaround for http://b/26394120 - will be removed before the release
+  if (fd == -1 && ns != &g_default_namespace && is_greylisted(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);
+  }
+  // END OF WORKAROUND
+
   return fd;
 }
 
@@ -1708,10 +1757,20 @@
   }
 
   if (!ns->is_accessible(realpath)) {
-    // do not load libraries if they are not accessible for the specified namespace.
-    DL_ERR("library \"%s\" is not accessible for the namespace \"%s\"",
-           name, ns->get_name());
-    return false;
+    // TODO(dimitry): workaround for http://b/26394120 - will be removed before the release
+    const soinfo* needed_by = task->get_needed_by();
+    if (is_greylisted(name, needed_by)) {
+      // print warning only if needed by non-system library
+      if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) {
+        DL_WARN("library \"%s\" (\"%s\") is not accessible for the namespace \"%s\" - the access is temporarily granted as a workaround for http://b/26394120",
+                name, realpath.c_str(), ns->get_name());
+      }
+    } else {
+      // do not load libraries if they are not accessible for the specified namespace.
+      DL_ERR("library \"%s\" is not accessible for the namespace \"%s\"",
+             name, ns->get_name());
+      return false;
+    }
   }
 
   soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);