Relax ELF header checks - warn for apps targeting pre-O

Bug: http://b/32581440
Test: bionic-unit-tests --gtest_filter=dl*:Dl*
Change-Id: I2fe356c67eb9665c671758117679a29b207219e4
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 069b004..8925926 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -221,3 +221,16 @@
 *Resolution*: we're aware of one middleware product that introduces these
 into your app. The middleware vendor is aware of the problem and has a fix
 available.
+
+## Invalid ELF header/section headers (AOSP master)
+
+Android loader now checks for invalid values in ELF header and section headers and fails
+if they are invalid.
+
+*Example error*
+dlopen failed: "/data/data/com.example.bad/lib.so" has unsupported e_shentsize: 0x0 (expected 0x28)
+
+*Resolution*
+Do not use tools that produce invalid/malformed elf-files. Note that using them puts application
+under high risk of being incompatible with future versions of Android.
+
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 1b18450..973fcf5 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -248,14 +248,26 @@
   }
 
   if (header_.e_shentsize != sizeof(ElfW(Shdr))) {
-    DL_ERR("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
-           name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
-    return false;
+    // Fail if app is targeting Android O or above
+    if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+      DL_ERR_AND_LOG("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
+                     name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
+      return false;
+    }
+    DL_WARN("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
+            name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
+    add_dlwarning(name_.c_str(), "has invalid ELF header");
   }
 
   if (header_.e_shstrndx == 0) {
-    DL_ERR("\"%s\" has invalid e_shstrndx", name_.c_str());
-    return false;
+    // Fail if app is targeting Android O or above
+    if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+      DL_ERR_AND_LOG("\"%s\" has invalid e_shstrndx", name_.c_str());
+      return false;
+    }
+
+    DL_WARN("\"%s\" has invalid e_shstrndx", name_.c_str());
+    add_dlwarning(name_.c_str(), "has invalid ELF header");
   }
 
   return true;