linker: warn about W+E load segments

No mapped segment from the elf file can be writable and
executable at the same time. This commit adds a warning
for malformed PT_LOAD segments in the elf-files.

Change-Id: I5e1e41bc2aabc209d3b07dd6ca2689a394294628
Test: flip protection flag for libtest_empty.so (used hexedit), adb sync
Test: run bionic-unit-tests and make sure it displays the warning.
Bug: http://b/30146890
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 3b60460..9ed612f 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -525,9 +525,18 @@
     }
 
     if (file_length != 0) {
+      int prot = PFLAGS_TO_PROT(phdr->p_flags);
+      // W + E PT_LOAD segments are not allowed.
+      if ((prot & (PROT_EXEC | PROT_WRITE)) == (PROT_EXEC | PROT_WRITE)) {
+        DL_WARN("\"%s\": has W+E (writable and executable) load segments. "
+                "This is a security risk shared libraries with W+E load segments "
+                "will not be supported in a future Android release. "
+                "Please fix the library.", name_.c_str());
+      }
+
       void* seg_addr = mmap64(reinterpret_cast<void*>(seg_page_start),
                             file_length,
-                            PFLAGS_TO_PROT(phdr->p_flags),
+                            prot,
                             MAP_FIXED|MAP_PRIVATE,
                             fd_,
                             file_offset_ + file_page_start);